为什么不能重载类模板?

Luc*_*lle 44 c++ templates overloading template-specialization language-lawyer

阅读这个问题让我想知道:是否存在禁止类模板重载的技术原因?

通过重载,我的意思是有几个模板具有相同的名称,但不同的参数,例如

template <typename T>
struct Foo {};

template <typename T1, typename T2>
struct Foo {};

template <unsigned int N>
struct Foo {};
Run Code Online (Sandbox Code Playgroud)

编译器设法处理重载的函数和函数模板,是不是可以将相同的技术(例如名称修改)应用于类模板?

起初,我认为这可能会在单独使用模板标识符时引起一些歧义问题,但唯一可能发生的情况是将其作为模板模板参数传递,因此参数的类型可用于选择合适的超载:

template <template <typename> class T>
void A {};

template <template <unsigned int> class T>
void B {};

A<Foo> a; // resolves to Foo<T>
B<Foo> b; // resolves to Foo<N>
Run Code Online (Sandbox Code Playgroud)

你认为这样的功能有用吗?是否存在一些"好"(即技术)原因,为什么在当前的C++中这是不可能的?

Tem*_*Rex 34

完整指南(亚马逊)模板的第12.5节包含此引用:

您可能合理地想知道为什么只有类模板可以部分专用.原因主要是历史原因.可能可以为函数模板定义相同的机制(参见第13章).

在某些方面,重载函数模板的效果是相似的,但也有一些细微的差别.这些差异主要与以下事实有关:在遇到使用时需要查找主模板.只有在之后才考虑专业化,以确定应该使用哪种实现.

相反,所有重载的函数模板必须通过查找它们进入重载集,并且它们可能来自不同的命名空间或类.这增加了在某种程度上无意中重载模板名称的可能性.

相反,也可以想象允许一种形式的类模板重载.这是一个例子:

// invalid overloading of class templates
template<typename T1, typename T2> class Pair; 
template<int N1, int N2> class Pair; 
Run Code Online (Sandbox Code Playgroud)

但是,似乎没有迫切需要这种机制.

此外,C++的设计和演变(亚马逊)在15.10.3节中包含了这个引用

因此,我得出结论,我们需要一种"专门化"模板的机制.这可以通过接受一般的重载或通过一些更具体的机制来完成.我选择了一个特定的机制,因为我认为我主要是解决由于C中的不规则引起的违规行为,并且因为过载的建议总是会引起抗议的嚎叫.我试图保持谨慎和保守; 我现在认为这是一个错误.最初定义的专业化是一种限制性和异常形式的重载,与其他语言的搭配很差.

大胆强调我的.我认为这说明函数重载解析比类特化更难实现(并且由用户使用).因此可能没有真正的技术障碍(类似于功能模板部分专业化),而是一个历史性事故.

  • 《C++ 的设计与演化》中的引用很有趣,因为它表明专业化最初被认为是重载的较弱形式,而实际上它们是两个截然不同的东西:重载允许指定基于以下条件选择的多个实现:使用的参数的*类型和数量*,而专业化与函数式编程中的[模式匹配](http://en.wikipedia.org/wiki/Pattern_matching)更相关,其中根据*值*选择实现论据。 (2认同)

log*_*og0 19

您不能"重载"类型参数,非类型参数和模板模板参数,但您可以专门使用可变参数模板:

template <typename... T>
struct Foo;

template <typename T1>
struct Foo<T1> {};

template <typename T1, typename T2>
struct Foo<T1,T2> {};
Run Code Online (Sandbox Code Playgroud)

  • +1虽然不允许模板重载的决定(我不喜欢这个名称,但缺乏更好的名称......)早就存在了可变参数模板.还要注意,这只能启用模板重载的一个子集,因为可变参数部分中的所有元素必须是相同的*种类*(在这种情况下类型,你不能提供专门的说法`template <int N,type T > struct Foo`. (2认同)
  • 对于具有可变数量的齐次参数,这是一个很好的解决方法. (2认同)