两个模板类可以相互用作模板参数,但如果我使用在一个类范围内定义的任何内容,则无法编译它。
template<class B> struct A {
typedef A *pointer;
};
template<class A> struct B {
//typedef A::pointer APtr;
//using APtr = A::pointer;
//APtr pa;
A::pointer pa;
};
struct AA;
struct BB;
struct AA : public A<BB> {};
struct BB : public B<AA> {};
VS2017 抱怨:
1>c:\test.cpp(59): warning C4346: 'pointer': dependent name is not a type
1>c:\test.cpp(59): note: prefix with 'typename' to indicate a type
1>c:\test.cpp(60): note: see reference to class template instantiation 'B<A>' being compiled
1>c:\test.cpp(59): error C2061: syntax error: identifier 'pointer'
1>c:\test.cpp(59): error C2238: unexpected token(s) preceding ';'
1>c:\test.cpp(69): warning C4091: '': ignored on left of 'A<BB> *' when no variable is declared
是否也涉及循环依赖?有没有一种可能的方法来解决它?
gcc 的错误信息提供了更多信息:
t.C:8:5: error: need ‘typename’ before ‘A::pointer’ because ‘A’ is a dependent scope
8 | A::pointer pa;
| ^
| typename
这样做,让 gcc 高兴:
template<class B> struct A {
typedef A *pointer;
};
template<class A> struct B {
//typedef A::pointer APtr;
//using APtr = A::pointer;
//APtr pa;
typename A::pointer pa;
};
struct AA;
struct BB;
struct AA : public A<BB> {};
struct BB : public B<AA> {};
这不是模板循环引用。第一个模板中唯一的引用是它自己的模板参数。仅仅因为它的模板参数恰好被命名为B
,并且有另一个模板定义了相同的名称,稍后,不会使模板参数成为另一个模板的引用。
就实际的类而言,前向声明(在本例中)使类之间的循环引用成为可能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句