如果我希望模板模板参数有一个争论,那么我可以按如下方式声明:
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支持)?
答案 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#中的敏捷原则,模式和实践
可变模板的好处可能是真实的,正如您自己指出的那样。但只要对它们的需求仍然是推测性的,我就不会添加它们。