为什么不可能重载类模板?(Why is it not possible to overload cl

2019-06-27 02:17发布

阅读这个问题使我想知道:是否有技术原因,禁止类模板重载?

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

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 ++?

Answer 1:

12.5节从模板的完全指南 ( 亚马逊 )包含了这句话:

你可以合法地问,为什么只有类模板可以部分专用。 其原因大多是历史。 这可能是可以定义函数模板(参见第13章)相同的机制。

在某些方面,重载函数模板的作用是相似的,但也有一些细微的差别。 这些差异主要与该主模板需要遇到使用时要抬头的事实。 该特只考虑之后,决定应该使用哪一个实现。

相反,所有重载函数模板必须进入通过查找它们设置过载,他们可能来自不同的命名空间或类。 这增加了几分无意超载模板名称的可能性。

反过来说,这也是可以想象的,允许类模板的重载的一种形式。 下面是一个例子:

 // invalid overloading of class templates template<typename T1, typename T2> class Pair; template<int N1, int N2> class Pair; 

然而,似乎没有成为这样一个机制迫切需要。

此外,C ++(演化的设计和 亚马逊 )包含此引用在第15.10.3

因此,我的结论是,我们需要对“专业”的模板机制。 这既可以通过接受一般超载或一些更具体的机制来实现。 我选择了一个特定的机制,因为我想我主要是解决造成用C违规违规行为和因超载的建议总是创造抗议的嚎叫。 我试图谨慎和保守的; 现在我认为这是一个错误 。 与最初定义专业化是与语言的其余不良装超载的限制,异常形态。

大胆重点煤矿。 我将此解释说,函数重载分辨率更难以实现(和用户得到正确的),比类专业化。 所以可能没有真正的技术障碍(与之相似的函数模板部分特例),而是一个历史的偶然。



Answer 2:

你不能“过载”类型参数,非类型参数和模板的模板参数,但你可以专注可变参数模板:

template <typename... T>
struct Foo;

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

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


Answer 3:

这已经有一段时间了,但我还是找到了这个帖子搜索时。 感谢@ log0为我提供一个良好的开端。 下面是避免需要对所有可能的枚举提供一个模板专业化的解决方案。 它确实让一个假设:你可以定义其基类的自身条件和每个模板的扩展。 (这将在完成FooImpl下文):

template <typename... T>
struct Foo;

template<typename T>
struct Foo<T> { /* implementation of base class goes here*/};

template <typename C, typename Base>
struct FooImpl : public Base { /* implementation of derived class goes here */};

template<typename C, typename... Bases>
struct Foo<C, Bases...> : FooImpl<C, Foo<Bases...> > { /*NO IMPLEMENTATION HERE */};

采用FooImpl打破了模棱两可的递归,否则结果。 这就允许声明如下所示:

Foo<int> foo_int;
Foo<int, double> foo_int_double;
Foo<int, float, double> foo_int_float_double;

也许,这就是STL现在该怎么做呢?



文章来源: Why is it not possible to overload class templates?