template<typename T>
struct A{
void method1(){}
};
template<>
struct A<int>{
void method2(){}
};
Run Code Online (Sandbox Code Playgroud)
方法1 A<int>和方法2都有?而且A<float>只会有method1?
jog*_*pan 16
每个专业化都会带来一种全新的数据类型(或者一个全新的模板,如果专业化只是部分的话).从标准(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()成员.此外,如果你也要method1()在A<int>专门化中引入它,它不需要具有相同的参数类型或返回类型A<float>::method1().
请参阅@ aschepler的答案,了解避免必须重写int案例的模板定义的可能方法.
asc*_*ler 12
@ 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() {}
};
Run Code Online (Sandbox Code Playgroud)
现在A<int>有成员method1和method2,但A<float>没有method2.
或(如果您可以修改主模板)...
#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
{}
};
Run Code Online (Sandbox Code Playgroud)
在template<int N>与N==N部分确保std::enable_if有一个相关的值,因此不会抱怨,直到有人实际上是尝试用A<T>::method2用不正确的T参数.
| 归档时间: |
|
| 查看次数: |
3116 次 |
| 最近记录: |