C++ 类模板部分专用化,而不专用化所有成员函数
c++ class template partial specialization without specializing all member functions
假设我有一个类X<'T,N'>,它定义了几个函数,我也希望类X<'T,3'>拥有它们,但也有一些额外的函数(一个现实生活中的例子是Vector<'T,N'>和Vector<'T,3'>将具有所有Vector<'T, N'>功能,但也可以实现3D空间中的旋转(
template <class T, size_t N>
class X {
public:
void a();
X<T, N> b(X<T, N> x);
// etc
static X<T, n> c();
protected:
T data[N];
};
1(部分专业化的方法
template <class T>
class X<T, 3> {
public:
void d();
};
template <class T>
using X3 = X<T, 3>;
a( [Y]std::hash<'X3<'T'>'>与std::hash<'X<'T、3'>'>相同,所以如果我重载X<'T、N'>、X3<'T'>的哈希也可以工作b( [Y] 函数
d是可访问的 c( [N] 函数 a、b、c 不可
访问
d( [Y/N]X3<'T'> x =X3<'T'>::c((;如果C可访问,将起作用
2(继承方法
template <class T>
class X3 : public X<T, 3> {
public:
void d();
};
a( [N]std::hash<'X3<'T'>'>与std::hash<'X<'T、3'>'>不同,所以如果我为 X<'T、N'>、X3<</strong>'T'>重载哈希将不适用b( [Y] 函数 d 可访问 c
( [Y/N]函数a、b、c 是可访问的,但b和c具有类似的强制转换问题(详见下文(d( [N] X3<'T'>
x =X3<'T'>::c((;不起作用,即使可访问
说明:
编译器知道如何将X3<'T'>转换为X<'T、3'>(因此将X3<'T'>作为参数传递给函数 b 有效(编译器不知道如何将 X<'T、3'> 转换为 X3<'T'>(因此将函数b和c结果分配给X3<'T'>变量不起作用(
(设法通过创建一个移动构造函数'X3(X<'T, 3'>&&x( noexcept'来绕过它,但在这种情况下仍然存在 std::hash 问题(
有没有办法将这两种方法的优点结合起来?
(除了使用方法 1(并重写所有这样的方法:(
//...
X3<T> b(X3<T> x) {
return X<T, 3>::b(x);
}
//...
(或方法2(和奇怪的转换,移动/复制构造函数,并且必须为std::hash之类的东西专门化几次模板(
根据我的经验,当您实际想要一个从模板继承的新类时,请使用继承方法 (2(。当部分特化与一般情况完全不同或根本没有定义一般情况时,只需声明一堆部分特化以使用 SFINAE,请使用方法 (1(。
如果您只想启用/禁用基于模板参数的类的方法,请使用 SFINAE。通过这种方式,您可以将所有定义集中在一个地方,并更轻松地推理它们。这是首选方法,除非您希望用户自行进行模板专用化 - 这通常不可取。
SFINAE 的例子:
template <class T, size_t N>
class X {
public:
void a() {...};
X<T, N> b(X<T, N> x);
// etc
static X<T, n> c() {...};
template<size_t uN = N, std::enable_if_t<uN==3,int>=0>
void d() {...};
protected:
T data[N];
};
在这里,X<int,3> x; x.d();
将编译,但X<int,2> x; x.d();
不会因为d()
方法被禁用,除非N==3
。
您可以在许多在线指南中阅读有关 SFINAE 在模板函数和类中的用法的更多信息(请注意,函数和类的语法完全不同(。
- 静态数据成员模板专用化的实例化点在哪里
- 成员变量如何使用专用类模板?
- GCC 7 中模板类的模板成员函数的专用化
- C++ 类模板部分专用化,而不专用化所有成员函数
- 专用于可变参数模板成员函数
- 对专用模板成员的未定义引用
- 对类模板成员的显式专用化的约束
- 具有专用成员函数的默认模板参数
- 如何正确地显式实例化具有完全专用成员的模板类
- C++模板类中的非专用成员
- 运算符<<重载时无法访问专用成员(指定指针)
- 避免强制转换以访问派生类的专用成员
- 枚举类型参数的专用成员模板
- 组织专用成员 Vector<Vector 接口的最佳方式<Type>>
- 基于基类的专用成员函数
- C++模板:专用成员函数,用于解决主模板中不明确的重载情况
- 导出/定义静态模板专用成员变量C++
- 无法访问QXmlStreamReader的专用成员(运算符=)
- 类专用成员-数组访问失败
- C++中非模板类的专用成员函数