Подтвердить что ты не робот

Шаблон переменной в шаблоне - непредвиденная ошибка (возможная ошибка?)

Наличие:

struct Value
{
    template<class T>
    static constexpr T value{0};
};

(0) ideone

template<typename TValue>
struct Something
{
    void x()
    {
        static_assert(TValue::template value<int> == 0, "");
    }
};

int main() { Something<Value>{}.x(); return 0; } 
  • Не компилируется с clang++ 3.6.

    error: не может ссылаться на переменную template 'value' без списка аргументов шаблона

  • Не компилируется с g++ 5.2.

    error: 'template constexpr const T Значение:: значение не является шаблоном функции


(1) ideone

Компилируется как с clang++, так и с g++.

struct Something
{
    void x()
    {
        static_assert(Value::template value<int> == 0, "");
    }
};

int main() { Something{}.x(); return 0; } 

Почему (0) не удается скомпилировать?

Кажется, что проблема возникает, если к шаблону переменной обращаются через параметр шаблона (в этом случае TValue). Определение псевдонима типа для TValue или использование ключевого слова typename не устраняет проблему.

Что здесь происходит?

4b9b3361

Ответ 1

Это определенно ошибка gcc и clang при обработке переменных шаблонов в качестве зависимых имен. Я отправил gcc 67248 и clang 24473.

В качестве обходного пути на данный момент оба компилятора поддерживают старый способ создания переменных шаблонов, а именно, если вы добавили:

struct Value
{
    template<class T>
    static constexpr T value = 0;

    template <typename T>
    struct variable_template_ish {
        static constexpr T value = Value::value<T>;
    };
};

то следующие компиляции:

template<typename TValue>
struct Something
{
    void foo() {
        static_assert(TValue::template variable_template_ish<int>::value == 0, "");
    }
};

int main() { 
    Something<Value>{}.foo();
}

Ответ 2

У меня были некоторые головные боли до создания файлов заголовков классов шаблонов в С++.

Убедитесь, что реализация static constexpr T value{0}; находится в том же заголовочном файле, что и объявление.