是否有任何理由使模板模板参数不可变

Is there any reason to make a template template parameter non variadic?

本文关键字:不可变 参数 任何 理由 是否      更新时间:2023-10-16

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

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支持)?

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

第二,及早检查。如果您不小心在S中向T传递了两个参数,编译器不会告诉您它是否是可变的,直到用户真正尝试使用它

第三,错误消息。如果用户传递了一个实际上需要两个参数的模板,那么在可变版本中,编译器会在S实例化T的那一行给他一条错误消息,所有的回溯都在这一行之间。在固定版本中,他在实例化S时会得到错误。

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

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

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

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

将猖獗的抽象应用于应用程序。相反,这需要开发人员只将抽象应用于程序的那些部分表现出频繁变化抵制过早的抽象是与抽象本身一样重要

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

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

相关文章: