C++模板模板参数

标签 c++ templates

#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;
}

Demo

关于C++模板模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52803490/

相关文章:

c++ - 如何使用 flex 和 bison 解析非常大的缓冲区

c++ - C++ 中的 this->variable 和 namespace::class::variable 有什么区别?

c++ - 用户定义的限定符

c++ - 我如何使用和专门化 'curious repeating template pattern'

c++ - g++ 模板类中的 undefined reference

c++ - 使用可变参数模板在 C++11 中调用函数参数

c++ - 与 C++ 应用程序的轻量级网络服务器通信

c++ - 设置 -fno-elide-constructors 时,clang Xcode 4.4.1 是否存在错误?

c++ - 任意顺序的多个标签的模板特化

C++ 模板未在 header /链接器错误中定义