MSVC2015 constexpr и вся эта шаблонная магия
От: Tujh Голландия  
Дата: 03.11.16 07:31
Оценка:
Добрый день.

Есть некая цель, выражающаяся в переводе числа в строку на этапе компиляции
STR(x) #x
не предлагать, нужна обработка с определённой логикой.
Следующий минимальный пример прекрасно отрабатывает на GCC/Clang, но не собирается в MSVC 2015, где вроде бы заявлена поддержка constexpr:
#include <iostream>

#define TAG 10000
/* calculate number of digits */
constexpr size_t num_digits(size_t x) {
    return x < 10 ? 1 : 1 + num_digits(x / 10);
}
/* storage for string data */
template<char... args>
struct metastring {
    const char data[sizeof... (args)] = { args... };
};
/* metastruct for string type */
template< size_t size, size_t x, char... args >
struct num_builder {
    typedef typename num_builder< size - 1, x / 10, '0' + (x % 10), args... >::type type;
};
/* proceed last digit */
template< size_t x, char... args >
struct num_builder< 1, x, args... > {
    typedef metastring< '0' + x, args... > type;
};
/* metaclass fro conversation  */
template<size_t x>
class __builder {
private:
    /* generate string type */
    typedef typename num_builder< num_digits(x), x, '\0' >::type type;
    /* string declaration */
    static constexpr type value{};
public:
    /*  */
    static constexpr const char* get() { // error C2059: syntax error: 'inline function header'
                                         // error C2059: syntax error: ''symbol''
                                         // error C2143: syntax error: missing ';' before '{'
                                         // error C2447: '{': missing function header (old-style formal list?)
        return value.data;
    }
};
/* instantiate string */
template< size_t x >
constexpr typename __builder< x >::type __builder< x >::value;
/* compile-time const for converted string */
static constexpr const char* tag = __builder< TAG >::get(); // error C2131: expression did not evaluate to a constant
                                                            // note: failure was caused by call of undefined function or one not declared 'constexpr'
                                                            // note: see usage of '__builder<10000>::get'
int main()
{
    std::cout << "Hello world!" << std::endl;
    std::cout << "tag = " << tag << std::endl;
    return 0;
}

Может кто подскажет, в чём проблема и как её решить? Или в MSVC всё не очень хорошо с поддержкой подобной "шаблонной магии" (может я что-то не правильно в ней понимаю) и проще отказаться от такого решения вообще?

Заранее благодарю за ответы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.