[c ++类模板的部分专业化,但不专门化所有成员函数

问题描述 投票:0回答:1

假设我有一个class X ] >>,它具有一些已定义的函数,我也希望class X 全部,还有一些其他功能 (一个现实的例子是Vector 和Vector 都具有Vector 函数,但也可以在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 '>] >>与std :: hash ' >因此,如果我为X 重载哈希,X3 将工作b)[Y]函数d可访问c] [N]函数a,b,c不可访问的d)[Y / N] X3 x = X3 :: c();如果[[caccesible,则将工作

[2)继承方法

template <class T> class X3 : public X<T, 3> { public: void d(); };

a] [N]

std :: hash '>] >>与std :: hash '>
因此,如果我为X X3 将不适用重载哈希b)[Y]函数daccesiblec] [Y / N]函数a,b,caccessible,但是bc具有相似的cast问题 (详细信息如下)d)[N] X3 x = X3 :: c(); 将不起作用,即使是可访问

解释:

编译器知道如何将X3 转换为X (因此将X3 作为函数b 作品)编译器不知道如何将X 转换为X3 (因此将函数bc结果赋给< [X3 变量不起作用)((通过创建移动构造函数'X3(X && x)noexcept'来绕过它,但是在这种情况下std :: hash问题仍然存在)

有没有办法结合两种方法的优点?

((使用方法1除外)并重写所有类似的方法:)

//... X3<T> b(X3<T> x) { return X<T, 3>::b(x); } //...
((或方​​法2)以及奇怪的转换,移动/复制构造函数,并且必须专门针对诸如std :: hash的对象进行模板几次)

假设我有一个X类,其中定义了一些函数,我也希望X类具有它们的全部,但是还希望有一些其他函数(现实中的例子是Vector&...

< [

根据我的经验,当您实际上想要一个从模板继承的新类时,请使用继承方法(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在模板函数和类中的用法的更多信息(请注意,函数和类的语法有很大不同。

c++ templates inheritance specialization partial-specialization
1个回答
0
投票
SFINAE的示例:
© www.soinside.com 2019 - 2024. All rights reserved.