C++模板模板参数语法

6

我对C++模板模板参数的语法感到困惑。尽管我理解了它们的有用性,正如这里优秀的描述一样,但我仍然觉得它们的语法难以理解。以下是来自上述网站的两个示例(还有其他示例):

template <typename T, template <typename> class Cont>
class Stack;

并且

template <template <typename,typename> class Cont>
class Wrapper3;

显然,如果没有理解这种语法背后的原理,就不可能概括这些声明。记忆更难,并且似乎没有太大帮助。
编辑: 我意识到我的问题尝试看起来像一个观察。我想要的是帮助如何用日常语言解释C++模板模板参数的语法。我可以使用C++语法和所有其他我学过的编程语言来做到这一点。然而,我很难“解释”C++模板模板参数的语法给自己听。我已经找到了一本书,“C++ templates : the complete guide” by David Vandevoorde and Nicolai M. Josuttis,虽然这是一本不错的书,但对于我理解这种语法并没有太大帮助,我相信许多人会认为这种语法最多是古怪的。

4
你的确切问题是什么? - Luc Touraille
我认为他没有理解这两个模板类之间的区别。 - xanatos
我理解这两个是不同的模板类。我遇到的问题是关于模板模板参数语法的。 - Olumide
我刚刚打了一个好回答... :-( - Kerrek SB
1
@Kerrek:很抱歉!不过,通过一些修改,这个问题可能很容易重新开放。 - Luc Touraille
1
@Luc 我已经尝试澄清我的问题。请重新考虑开放我的问题。谢谢。 - Olumide
2个回答

18

我不确定您的问题具体是什么,但以下是您提供的两个示例的解释。

template <typename T, template <typename> class Cont>
class Stack;

Stack 是一个类模板,有两个模板参数。第一个参数 T 可以是任何类型(包括内置类型、用户定义类型、模板实例等)。第二个参数 Cont 必须是一个带有一个参数的类模板。该参数未命名,因为这没有太多意义(该参数从未绑定到任何内容)。

template <template <typename,typename> class Cont>
class Wrapper3;

Wrapper3是一个只有一个参数Cont的类模板,Cont必须是一个具有两个参数的类模板。

定义模板模板参数的语法与定义类模板的语法相同(template <typename [param1], typename [param2], ...> class Name),因此我不太明白您的问题所在。

然而,当您开始“嵌套”模板模板参数时,语法可能会变得有点笨拙:

// class template whose parameter must be a class template whose parameter
// must be a class template
template <template <template <typename> class > class C >
struct Wow {};

不过这种情况并不经常发生...

“[template template]”参数未命名,因为它没有太多意义(该参数从未绑定到任何内容)。这是否意味着template <template <typename E> class C> class Foo { C<E> myField; }是不允许的? - mucaho
1
@mucaho 你可以给参数命名,但是你不能使用它,因为它从未绑定到任何类型。例如,假设你有类 template <typename T> class Bar {}:你可以使用它来实例化 Foo,如下所示:Foo<Bar> f。在这种情况下,E表示的是什么类型?如果你想写 Foo<Bar<int>>,那么你不需要一个模板模板参数,只需要一个常规的非模板参数即可。 - Luc Touraille

4

这并不是什么神秘的事情。只需要从原始模板中删除你的模板参数:

template <typename> class Cont

任何只有一个类型参数的类模板都可以使用,例如:
template <typename T>
class A {
public:
  A(T t) : t_(t) {}
  T get() { return t_; }
private:
  T t_;
};

您可以使用原始模板作为

Stack<int, A> s;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接