This doesn't compile:
template<class X> struct A { template<int I> void f() {} }; template<class T> void g() { A<T> a; a.f<3>(); // Compilation fails here (Line 18) } int main(int argc, char *argv[]) { g<int>(); // Line 23 }
The compiler (gcc) says:
hhh.cpp: In function 'void g()':
hhh.cpp:18: error: expected primary-expression before ')' token
hhh.cpp: In function 'void g() [with T = int]':
hhh.cpp:23: instantiated from here
hhh.cpp:18: error: invalid use of member (did you forget the '&' ?)
Can anyone explain why this is? Is there a way to get it to work?
When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6. 2), the member template name must be prefixed by the keyword template .
For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.
Member functions can be function templates in several contexts. All functions of class templates are generic but are not referred to as member templates or member function templates. If these member functions take their own template arguments, they are considered to be member function templates.
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
Try the following code:
template<class T> void g() { A<T> a; a.template f<3>(); // add `template` keyword here }
According to C++'03 Standard 14.2/4:
When the name of a member template specialization appears after
.
or->
in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keywordtemplate
. Otherwise the name is assumed to name a non-template.
Future C++ Standard seems to be still require this keyword according to draft n2857 14.3/4. Some compilers has special mode that allows to compile original code without errors (Comeau compiles it in so called relaxed mode).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With