有没有理由使模板模板参数不可变?

时间:2014-01-10 10:35:09

标签: c++ templates c++11 variadic-templates template-templates

如果我希望模板模板参数有一个争论,那么我可以按如下方式声明:

template<template<typename> class T>
struct S {
    T<int> t_;
    //other code here
}

但是,如果我以后想要提供一个模板模板参数,该参数需要两个参数,其中第二个具有默认值(如std :: vector)T<int> t_;仍然有效,但模板不匹配{{1} }。我可以通过将template<typename> class T变为可变参数模板模板template<typename> class T来解决此问题。现在我的代码更灵活。

我以后是否应该将所有模板模板参数变为可变参数?有什么理由我不应该(因为其他原因我的代码已经需要C ++ 11支持)?

2 个答案:

答案 0 :(得分:5)

首先,文档。如果参数是可变参数,用户现在需要检查一些其他来源,以发现这确实需要一些需要一个模板参数的东西。

第二,提前检查。如果您在T中意外地将两个参数传递给S,编译器将不会告诉您它是否为可变参数,直到用户实际尝试使用它为止。

第三,错误消息。如果用户传递实际需要两个参数的模板,则在可变参数版本中,编译器将在S实例化T的行上给出错误消息,其中包含所有回溯内容。在固定版本中,他在实例化S时收到错误。

第四,没有必要,因为模板别名也可以解决这个问题。

S<vector> s; // doesn't work
// but this does:
template <typename T> using vector1 = vector<T>;
S<vector1> s;

所以我的结论是,不要让事情变得多变。实际上你并没有获得灵活性,只是减少了用户必须编写的代码量,但代价是可读性较差。

答案 1 :(得分:2)

如果您已经知道您很可能需要它,那么您应该添加它。否则,你不需要它(YAGNI)所以它会增加更多东西来维护。它类似于首先拥有模板参数的决定。特别是在TDD类型的环境中,只有在需要时才会重构,而不是过早抽象。

  

将猖獗的抽象应用于每个部分也不是一个好主意   应用程序。相反,它需要奉献精神   开发人员只将抽象应用于程序的那些部分   表现出频繁的变化。 抵制过早抽象是如此   作为抽象本身很重要

     罗伯特C.马丁   第132页,C#中的敏捷原则,模式和实践

可变模板的好处可能是真实的,正如您自己指出的那样。但只要对它们的需求仍然是推测性的,我就不会添加它们。