Шаблон переменной в шаблоне - непредвиденная ошибка (возможная ошибка?)
Наличие:
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; }
(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
не устраняет проблему.
Что здесь происходит?
Ответы
Ответ 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};
находится в том же заголовочном файле, что и объявление.