template <template <class> class T>
class A {};
template <typename T>
class B {
A<B> member;
};
int main()
{
B<int> b;
return 0;
}
error: template argument for template template parameter must be a class template
A<B> member;
^
B
的类体中的符号 B
是一个已经实例化过的类型, 不能够被传递给模板类 A
用于实例化.而 g++ 4.7 可以正确编译通过, 说明 g++ 肯定内置了某种脑补机制, 能灵活处理这样的情况, 它甚至可以编译如下分裂的代码
template <template <class> class T>
class A {};
template <class T>
class C {};
template <typename T>
class B {
A<B> member;
C<B> another;
};
int main()
{
B<int> b;
return 0;
}
B
定义在全局名字空间中, 所以代码应该这样修改template <template <class> class T>
class A {};
template <typename T>
class B {
A< ::B> member;
};
int main()
{
B<int> b;
return 0;
}
< ::
, 这绝不是我手残了抖上去的, 而是这地方必须要一个空格. C++ 程序设计领域流行着各种都市传说, 其中有模板套模板结束时的两个大于号之间要加个空格什么的, 类似, 小于号跟冒号之间也要加个空格, 否则 <:
会被认为是 [
.相应地, 如果
B
定义于某个有名字的名字空间 (这话说得...) 中那么上面代码应作相应修改template <template <class> class T>
class A {};
namespace ns {
template <typename T>
class B {
A<ns::B> member;
};
}
int main()
{
ns::B<int> b;
return 0;
}