阅读this question让我想知道:是否有技术上的原因禁止类模板重载?
通过重载,我的意思是有几个模板具有相同的名称,但不同的参数,例如
template <typename T>
struct Foo {};
template <typename T1, typename T2>
struct Foo {};
template <unsigned int N>
struct Foo {};
编译器设法处理重载函数和函数模板,难道不可能应用相同的技术(例如:例如,名称篡改)到类模板?
一开始,我认为单独使用模板标识符可能会导致一些歧义问题,但唯一可能发生这种情况的情况是将其作为模板参数传递时,因此参数的类型可以用于选择适当的重载:
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>
你认为这样的功能有用吗?有没有“好”(一)这在当前的C++中是不可能的。
3条答案
按热度按时间w8f9ii691#
您可能会想知道为什么只有类模板可以部分专用化。原因主要是历史性的。也许可以为函数模板定义相同的机制(参见第13章)。
在某些方面,重载函数模板的效果是相似的,但也有一些细微的差异。这些差异主要与以下事实有关:当遇到使用时,需要查找主模板。专门化只是在之后才考虑,以确定应该使用哪种实现。
相反,所有重载的函数模板都必须通过查找它们而被带入重载集,它们可能来自不同的命名空间或类。这在一定程度上增加了无意中重载模板名称的可能性。
相反,也可以想象允许类模板的重载形式。下面是一个例子:
然而,似乎并不迫切需要这样的机制。
此外,the Design and Evolution of C++(Amazon)在第15节中包含了这句话。10.3
因此,我得出结论,我们需要一种“专门化”模板的机制。这可以通过接受一般的重载或通过一些更具体的机制来实现。我选择了一个特定的机制,因为我认为我主要是解决由C中的违规行为引起的违规行为,并且因为超载的建议总是会引起抗议。我试图保持谨慎和保守;我现在认为这是一个错误最初定义的专业化是一种受限制的、反常的重载形式,与语言的其他部分格格不入。
大胆强调我的。我将此解释为函数重载解析比类专门化更难实现(并被用户正确理解)。所以可能没有真实的的技术障碍(类似于函数模板部分专门化),而是一个历史事故。
7uzetpgm2#
你不能“重载”类型参数、非类型参数和模板参数,但你可以专门化可变参数模板:
sbdsn5lh3#
这已经有一段时间了,但我在搜索时仍然发现了这篇文章。感谢@log0为我提供了一个良好的开端。这里有一个解决方案,它避免了为所有可能的枚举提供模板专门化。它做了一个假设:您可以根据模板本身及其基类来定义每个模板展开。(这将在下面的
FooImpl
中完成):FooImpl
的使用打破了否则会导致的二义性递归。这样就允许进行如下声明:也许这就是STL现在所做的?