6

如果我希望模板模板参数有一个论点,那么我可以将其声明如下:

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

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

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

4

2 回答 2

5

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

第二,早检查。如果您不小心将两个参数传递给Tin S,编译器不会告诉您它是否是可变参数,直到用户实际尝试使用它。

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

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

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

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

于 2014-01-10T10:44:49.527 回答
2

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

将猖獗的抽象应用于应用程序的每个部分也不是一个好主意。相反,它需要开发人员致力于将抽象仅应用于程序中那些表现出频繁变化的部分。抵制过早抽象与抽象本身一样重要

Robert C. Martin 第 132 页,C# 中的敏捷原则、模式和实践

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

于 2014-01-10T10:41:46.690 回答