#include <iostream>
using namespace std;
template <typename T = int>
struct Foo {
T t;
Foo() { cout << "Foo" << endl; }
};
template <typename T>
struct Baz {
T t;
Baz() { cout << "Baz" << endl; }
};
template <typename T>
struct Bar {
T t;
Bar() { cout << "Bar" << endl; }
};
template <template <typename X> class T>
struct Bar {
T data;
Bar() : data() { cout << "Bar" << endl; }
};
int main()
{
Bar<Foo<>> a;
Bar<Baz<float>> b;
Bar<int> c;
return 0;
}
我刚刚开始学习模板。而且我真的对模板模板参数感到困惑。我知道您将模板作为参数传递。在我的 Bar 模板类中,它接收模板模板参数,<typename X>
是做什么的?代表?是typename X
class T
的模板参数?
template <template <typename X> class T>
struct Bar {
T data;
Bar() : data() { cout << "Bar" << endl; }
};
此外,当我在主函数中调用我的模板模板参数时,我得到错误消息,指出 Bar 没有默认构造函数。这是为什么?
最佳答案
template 模板参数允许您将模板传递给其他模板。 它们不是具体类型,需要参数化才能使它们实例化。
In my template class for Bar where it receives a template template argument, what does
<typename X>
represent?
From the standard [basic.scope.temp] ;
The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.
这基本上是说该名称仅在该模板模板的参数列表中可用。
在许多情况下,只需输入 typename
就足够了没有模板模板参数的名称,但名称可用于记录您的代码。
然而,如果另一个非类型模板参数依赖于它,则给它起一个名字是有用的。
对于 example , template <template <typename X, X> typename Y>
.
关于您的示例代码,Bar 的第二个声明有两个问题。首先是 Bar 已经声明为接受类型,而不是模板。 您的第二个声明冲突,因为它被声明为接受模板。
此处您需要的是 Bar 的特化,其中特化解析为与主模板匹配的单个类型。 例如,
template <template <typename> class T,typename Y>
struct Bar<T<Y>> {
T<Y> data;
Bar() : data() { cout << "Bar" << endl; }
};
这里需要注意的重要一点是,特化中的模板参数可以是您需要的任何内容。是struct Bar
之后的部分必须与主模板匹配。特化中的所有参数都将从作为模板参数传递给 Bar 实例化的类型推导出来。
您的第二个问题是您将 Bar 的成员声明为 T 类型。在第二种情况下 T 是一个模板,您无法实例化一个模板 无需对其进行参数化。
这是您的代码的工作示例,其中包含 Bar 的特化。
#include <iostream>
using namespace std;
template <typename T = int>
struct Foo {
T t;
Foo() { cout << "Foo" << endl; }
};
template <typename T>
struct Baz {
T t;
Baz() { cout << "Baz" << endl; }
};
template <typename T>
struct Bar {
T t;
Bar() { cout << "Bar" << endl; }
};
template <template <typename > class T,class Y>
struct Bar<T<Y>>
{
T<Y> data;
Bar() : data() { cout << "Bar Specialization" << endl; }
};
int main()
{
Bar<Foo<>> a; //matches the specialization with T = template<typename> Foo and Y=int
Bar<Baz<float>> b; //matches the specialization with T = template<typename> Baz and Y=float
Bar<int> c; //matches the primary template with T=int
return 0;
}
关于C++模板模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52803490/