Например:Как следует ссылаться на Variable Template в C++ 14 при объявлении в классе?
class example{
public:
template <class T> static constexpr T var = T(1.5);
};
int main(){
int a = example::var<int>;
example obj;
int b = obj.var<int>;
return 0;
}
GCC производит ошибку для обоих: 'example::var<T>' is not a function template
и 'var' is not a member template function
Clang правильно компилирует первым, но выдает ошибку для второго: cannot refer to member 'var' in 'example' with '.'
В соответствии с C + +14 Стандарт (ISO/IEC 14882: 2014):
Раздел 14, абзац 1.
A variable template at class scope is a static data member template.
Раздел 9.4, Пункт 2.
A static member s of class X may be referred to using the qualified-id expression X::s; it is not necessary to use the class member access syntax (5.2.5) to refer to a static member. A static member may be referred to using the class member access syntax, in which case the object expression is evaluated.
Поэтому, имхи, переменный шаблон в области видимости класса (т.е. шаблон члена статических данных) может быть передан в обоих направлениях. Может быть, это ошибка в компиляторах?
Единственное, что я нашел, чтобы попытаться оправдать такое поведение это предложение в разделе 9.4.2, пункт 1:
A static data member is not part of the subobjects of a class.
Однако две вышеупомянутые пункты остаются в силе. Кроме того, я попробовал тот же пример, ссылаясь на другие статические элементы, такие как переменная, функция и шаблон функции, и все они успешно компилируются как в GCC, так и в Clang.
class example{
public:
static int constexpr variable = 1;
void static function(){ return; }
template <class T> void static function_template(){ return; }
};
int main(){
example obj;
int a = obj.variable;
int b = example::variable;
obj.function();
example::function();
obj.function_template<int>();
example::function_template<int>();
return 0;
}
Thanks in Advance.
Примечание 1: версии компилятора - clang 3.7.0 и gcc 5.2.1.
Примечание 2: ключевое слово static
требуется: Variable template at class scope
Примечание 3: так как я хочу, чтобы инициализировать переменную шаблона, ключевое слово constexpr
также требуется, потому что в моем настоящем коде я его экземпляр с плавающей точкой, двойной и (см. C++ 14 Standard (ISO/IEC 14882: 2014), раздел 9.4.2, параграф 3).
Примечание 4: фактические «определения» этих статических элементов данных вне класса (т. Е. template <class T> constexpr T example::var;
) не нужны в этих примерах. Я тоже пытался, но это не имеет значения.
Какая версия gcc вы используете? g ++ 6.2 ведет себя как clang. Но в отличие от clang, сообщение об ошибке для 'obj.var' состоит в том, что * "' var' не является функцией шаблона члена * *. Кажется, что первая часть была исправлена с g ++ 5. –
Holt
Я использую gcc 5.2.1 и clang 3.7.0 :) –
Clang trunk принимает этот код. –