h********n 发帖数: 1671 | 1 这个例子中,模板类B中引用了模板类A的模板函数f(),但是gcc无法识别这个用法。
template< typename T >
struct A
{
template< typename U >
int f (){ return 0; }
};
template< typename T >
struct B
{
A< T > a; // error
//A a; // ok
int g (){ return a.f< char >(); }
};
int main()
{
B< int > b;
return b.g();
}
U:\tmp\test.cpp: In member function 'int B::g()':
U:\tmp\test.cpp:15:31: error: expected primary-expression before 'char'
U:\tmp\test.cpp:15:31: error: expected ';' before 'char'
U:\tmp\test.cpp:15:36: error: expected unqualified-id before '>' token
在类B中,因为T为未知类型,所以a也为未知类型,所以编译器认为a.f是a的一个成员
变量,然后将'<'理解成小于号,于是要求在'<'的右侧出现一个primary-expression。
如果f是一个class,当然可以在前面加typename告诉编译器'<'表示模板参数,不是小
于号,但这个情况下typename显然行不通。那么如何告诉编译器这里'<'代表一个模板
函数的参数列表,而不是小于号呢?
如果将 A a 改成 A a 就没有这个问题,因为这时a的类型为已知,编译器就
会知道f是一个模板函数。 |
t****t 发帖数: 6806 | 2 return a.template f();
【在 h********n 的大作中提到】 : 这个例子中,模板类B中引用了模板类A的模板函数f(),但是gcc无法识别这个用法。 : template< typename T > : struct A : { : template< typename U > : int f (){ return 0; } : }; : template< typename T > : struct B : {
|
t****t 发帖数: 6806 | 3 The reason is A::f is a member template. Otherwise it is ok.
[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 keyword
template. Otherwise the name is assumed to name a non-template. [Example:
class X {
public:
template X* alloc();
template static X* adjust();
};
template void f(T* p)
{
T* p1 = p->alloc<200>();
// ill-formed: < means less than
T* p2 = p->template alloc<200>();
// OK: < starts template argument list
T::adjust<100>();
// ill-formed: < means less than
T::template adjust<100>();
// OK: < starts template argument list
}
—end example]
【在 h********n 的大作中提到】 : 这个例子中,模板类B中引用了模板类A的模板函数f(),但是gcc无法识别这个用法。 : template< typename T > : struct A : { : template< typename U > : int f (){ return 0; } : }; : template< typename T > : struct B : {
|
h********n 发帖数: 1671 | 4 受教了。以前试过加template,不过按typename的习惯加到a.f()的前面去了。 |