模板专门化是否扩展或覆盖泛型模板
Does a template specialization extend or override the generic template?
template<typename T>
struct A{
void method1(){}
};
template<>
struct A<int>{
void method2(){}
};
A<int>
是否同时具有method1和method2?而A<float>
只有method1
?
每个专门化都带来一个全新的数据类型(或者一个全新的模板,如果专门化只是部分的话)。来自标准(c++ 11):
(§14.5.5/2)每个类模板部分特化是一个不同的模板,应该为模板部分特化的成员提供定义(14.5.5.3)。
:
(§14.5.5.3/1)[…类模板部分特化的成员与主模板的成员无关。类模板部分特化成员的使用方式需要定义,必须定义;主模板成员的定义永远不能用作类模板部分专门化成员的定义。[…]
上述内容是在部分专门化的上下文中陈述的,但它也适用于显式专门化(就像您的情况一样),尽管标准对此没有明确说明。
还要注意,你不仅需要声明你想要在专门化中使用的所有成员函数,而且还需要定义它们(在这里,标准甚至对显式专门化也非常清楚):
(14.7.3/5)显式特化类的成员不是从类模板的成员声明中隐式实例化的;相反,如果需要的话,类模板专门化的成员本身应该被显式地定义。在这种情况下,类模板显式特化的定义应该在作用域中在定义成员的点。显式专门化类的定义与生成的专门化的定义无关。也就是说,它的成员不必具有与生成的专门化成员相同的名称、类型等。[…]
因此,确实,A<int>
将只有method2()
, A<float>
将只有method1()
作为成员。此外,如果您要在A<int>
专门化中也引入method1()
,则它不需要具有与A<float>::method1()
相同的参数类型或返回类型。
请参阅@aschepler的答案,了解避免为int
情况重写模板定义的可能方法。
@jogojapan的答案解释了这种语言的作用。如果您确实想为特定的专门化添加新成员,这里有一些变通方法:
template<typename T>
struct A_Base {
void method1() {}
};
template<typename T>
struct A : public A_Base<T> {};
template<>
struct A<int>
: public A_Base<int>
{
void method2() {}
};
现在A<int>
有成员method1
和method2
,但是A<float>
没有成员method2
。
OR(如果你可以修改主模板)…
#include <type_traits>
template<typename T>
struct A {
void method1() {}
template<int N=0>
auto method2() ->
typename std::enable_if<std::is_same<T, int>::value && N==N>::type
{}
};
template<int N>
和N==N
部分确保std::enable_if
有一个依赖值,因此不会抱怨,直到有人实际上试图使用A<T>::method2
和不正确的T
参数。
由于这个问题和答案似乎仍然受到关注,因此在c++ 20中稍后的编辑中添加了它,您可以简单地这样做:
#include <type_traits>
template<typename T>
struct A {
void method1() {}
void method2() requires std::is_same_v<T, int> {}
};
专门化取代泛型模板。因此,A<int>
将只有method2()
,当然,A<double>
将只有method1()
。
- 错误处理.将系统错误代码映射到泛型
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 链表的泛型函数remove()与成员函数remove)
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何编写将要继承的泛型代码?
- C++17 如何保存泛型可调用对象以供以后使用
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- C++泛型类错误,问题出在哪里?
- C++泛型类,单独实现?
- 将参数传递给泛型 lambda 时复制构造函数不正确
- 泛型枚举和其他类型的重载模板函数
- 使用泛型类型推送到堆栈时出现问题
- 可变参数泛型 lambda 和函数重载
- C++ 泛型和多态性:这种模式可行吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- Java 是否像C++模板一样具有泛型推论?
- 为堆栈实现泛型集合
- 如何覆盖 'const T&' 和 'T&&' 的泛型函数,其中 T 可以作为引用?
- 模板专门化是否扩展或覆盖泛型模板