Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++14 | How should a Variable Template be referred to when declared at Class scope?

22 views
Skip to first unread message

jose...@solidsands.nl

unread,
Jan 3, 2017, 4:43:29 AM1/3/17
to
For example:

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 produces error for both: 'example::var<T>' is not a function template and 'var' is not a member template function

Clang compiles correctly the first one but produces an error for the second: cannot refer to member 'var' in 'example' with '.'

According to the C++14 Standard (ISO/IEC 14882:2014):

Section 14, Paragraph 1.

A variable template at class scope is a static data member template.
Section 9.4, Paragraph 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.
Therefore, IMHO, a Variable Template at Class scope (i.e., a Static Data Member Template) could be referred to in both ways. Could it be a bug in the compilers?

The only thing I found to try to justify this behaviour is this sentence in Section 9.4.2, Paragraph 1:

A static data member is not part of the subobjects of a class.
However, the two aforementioned paragraphs are still valid. Besides, I tried the same example referring to other static members such as a variable, a function and a function template, and all of them compile successfully in both GCC and 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.

Note 1: compiler versions are clang 3.7.0 and gcc 5.2.1.

Note 2: the keyword static is required: http://stackoverflow.com/questions/21474111/variable-template-at-class-scope

Note 3: since I want to initialize the variable template, the keyword constexpr is also required because in my actual code I will instantiate it with float, double and long double (see C++14 Standard (ISO/IEC 14882:2014), Section 9.4.2, Paragraph 3).

Note 4: actual "definitions" of these static data members outside the class (i.e., template <class T> constexpr T example::var;) are not needed in this example cases. I also tried though, but it makes no difference.

Alf P. Steinbach

unread,
Jan 3, 2017, 5:09:40 AM1/3/17
to
On 03.01.2017 10:43, jose...@solidsands.nl wrote:
> 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;
> }

[example]

[C:\my\forums\clc++\047]
> g++ --version | find "++"
g++ (tdm64-1) 5.1.0

[C:\my\forums\clc++\047]
> g++ foo.cpp -Wno-unused-variable
foo.cpp: In function 'int main()':
foo.cpp:11:17: error: 'var' is not a member template function
int b = obj.var<int>;
^

[C:\my\forums\clc++\047]
> cl /nologo- 2>&1 | find "++"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86

[C:\my\forums\clc++\047]
> cl foo.cpp /wd4189 /wd4101
foo.cpp

[C:\my\forums\clc++\047]
> _
[/example]

Neither compiler has a problem with a template /function/ accessed this
way, so it's evidently about template variables being A New Thing™.

Note: while the MSVC compiler is current, the g++ compiler used here is
old; I believe the current version is 6.1 or something like that.

Cheers & hth.,

- Alf

jose...@solidsands.nl

unread,
Jan 3, 2017, 5:48:01 AM1/3/17
to
Thanks Alf, I agree with you. Thanks for the answer :)
0 new messages