【发布时间】:2016-01-17 02:02:25
【问题描述】:
我在我的 C++ 项目中使用模板,但在使用模板类型作为模板模板参数时遇到了问题。我认为描述它的最好方法是举一个产生错误的例子:
template <template<class> class P, typename T>
class Foo {
P<T> baz;
};
template <class T>
class Bar {
Foo<Bar, T> memberFoo;
void makeFoo() {
Foo<Bar, T>* f = new Foo<Bar, T>();
}
};
Foo<Bar, int> globalFoo;
globalFoo 的声明不会导致错误,但memberFoo 和f 的声明会导致编译器错误:
错误:模板模板参数的模板参数必须是类模板 或输入别名模板
只有在 Bar 类的声明中使用 Bar 作为模板参数时才会发生该错误,但同时使用 clang 和 g++ 都会发生该错误。这似乎会记录在某处,但谷歌搜索不会产生 SO 问题或其他文档。
在 C++ 中这种使用模板是不合法的,还是我对如何定义和使用模板有误解?如果 C++11 标准不允许这种设计架构,我可以使用什么解决方法?
【问题讨论】:
-
我认为问题在于,在
Bar的定义中,纯名称Bar指的是this 专业化——即Bar<T>——而不是模板作为一个整体。一种解决方法:在Bar定义的顶部添加template <typename U> using Bar2 = Bar<U>;,并在需要引用非专业模板的地方使用Bar2代替Bar。 -
这似乎是递归的。 Bar 有一个 Foo 成员,但是 Foo 是模板化的,因此它具有与它所属的类完全相同的 Bar 成员。所以 Bar
包含自己,这是不允许的。我认为,特定错误是由于在定义期间尝试使用 Bar 作为模板模板参数而没有前向声明引起的。