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