Шаблон переменной в классе шаблона - непредвиденная ошибка (возможная ошибка?)
Наличие:
struct Value
{
template<class T>
static constexpr T value{0};
};
(0) идеон
template<typename TValue>
struct Something
{
void x()
{
static_assert(TValue::template value<int> == 0, "");
}
};
int main() { Something<Value>{}.x(); return 0; }
Не компилируется с clang++ 3.6.
ошибка: не может ссылаться на шаблон переменной 'значение' без списка аргументов шаблона
Не компилируется с g++ 5.2.
ошибка: 'template constexpr const T Value::value' не является шаблоном функции
(1) идеон
Компилируется с использованием clang ++ и g ++.
struct Something
{
void x()
{
static_assert(Value::template value<int> == 0, "");
}
};
int main() { Something{}.x(); return 0; }
Почему (0) не компилируется?
Кажется, что проблема возникает, если доступ к шаблону переменной осуществляется через параметр шаблона (в данном случае TValue
). Определение псевдонима типа для TValue
или используя typename
Ключевое слово не решает проблему.
Что тут происходит?
2 ответа
Это определенно ошибка gcc и clang при обработке шаблонов переменных как зависимых имен. Я представил gcc 67248 и лязг 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();
}
У меня были некоторые головные боли раньше при создании файлов заголовков классов шаблонов в C++.
Убедитесь, что вы реализуете static constexpr T value{0};
находится в том же заголовочном файле, что и объявление.