2015-08-17 1 views
19

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

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; } 
  • Не компилировать с лязгом ++ 3,6.

    error: cannot refer to variable template 'value' without a template argument list

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

    error: ‘template constexpr const T Value::value’ is not a function template


(1) ideone

компилирует с обоими лязг ++ и G ++.

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

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

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

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

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

+1

Что такое 'template static constexpr T value {0};' предполагается делать? Это что-то новое? Как это называется? –

+4

@ BЈовић, Он называется * переменным шаблоном *, добавленным в C++ 14. См. [This] (https://en.wikipedia.org/wiki/C%2B%2B14#Variable_templates) (wiki) и [this] (http://en.cppreference.com/w/cpp/language/variable_template) (cppreference) – Nawaz

+2

(0) терпит неудачу для меня на clang 3.6, с «не может ссылаться на шаблон переменной« значение »без списка аргументов шаблона» – Barry

ответ

10

Это определенно ошибка 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(); 
} 
+1

Я * знал * это была ошибка. Странно, что и gcc и clang ошиблись. Обходной путь, который я использовал, фактически определял функции 'static constexpr', которые завернули переменные. –

0

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

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

+1

Это должен быть комментарий, а не ответ –

+1

Это должно быть включено как комментарий, а не ответ – gpullen

+0

Спасибо. Это был мой первый ответ ... извинения :-) –

 Смежные вопросы

  • Нет связанных вопросов^_^