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

Наличие:

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.

    ошибка: нельзя ссылаться на шаблон переменной ‘значение’ без списка аргументов шаблона

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

    ошибка: ‘template constexpr const T Value :: value’ не является шаблоном функции


(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 Ключевое слово не решает проблему.

Что тут происходит?

19

Решение

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

Другие решения

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

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

0

По вопросам рекламы [email protected]