当仅与少数成员不同时,有必要对整个类进行专门化吗?

Is it necessary to specialize whole class, when differs just with few members?

本文关键字:专门化 成员      更新时间:2023-10-16

我正在设计类,这对于2d和3d几乎是相同的,所以我试图使用模板,将其创建为一个由矢量类型(2d od 3d)类型的类

对于2d和3d,有些方法和成员非常相同

一些(但很少)方法略有不同,我在这里使用trait -参见doSomething()

一些成员和方法存在于3d,但不存在于2d(向上向量),这是我的问题。

我可以通过完全的类专门化来解决这个问题,但是有没有其他的方法,如何在不专门化整个类的情况下包含/排除这些成员?

我有特质:

template<typename T>
struct VectorInfo{};
template<>
struct VectorInfo<Vec2>
{
    enum { dim = 2 };
};
template<>
struct VectorInfo<Vec3>
{
    enum { dim = 3 };
};
template<int Val>
struct VectorDimension
{
    enum { val = Val };
};

和类:

template <typename vector_type>
class LocalSpace
{
public:
    ////////////////////////////////////////
    //Common for 2D and 3D
    const vector_type & getSideVector() const;      
    void setSideVector(const vector_type & s);
    const vector_type & getForwardVector() const;
    void setForwardVector(const vector_type & f);
    const vector_type & getPosition() const;
    void setPosition(const vector_type & p);
    bool isRightHanded() const;
    //others methods...
    //////////////////////////////////////////
    //only for 3D
    const vector_type & getUpVector() const;    
    void setUpVector(const vector_type & u);   
    //One of few methods differing for 2D and 3D 
    inline void doSomething(const vector_type & v)      
    {
        doSomethingImpl(v, VectorDimension<VectorInfo<vector_type>::dim>);
    }
protected:
    void doSomethingImpl(const vector_type & v, VectorDimension<2>)
    {
    }
    void doSomethingImpl(const vector_type & v, VectorDimension<3>)
    {
    }
private:
    vector_type m_side;     //2d+3d        
    vector_type m_forward;  //2d+3d
    vector_type m_up;       //3d ONLY
    vector_type m_position; //2d+3d
};

希望你能理解我的问题。

编辑:

谢谢你的回复,现在我有

struct BlankType{};
template <typename vector_type>
class LocapSpace3DBase
{
public:
    const vector_type & getUpVector() const;
    void setUpVector(const vector_type & u);
private:
    vector_type m_up;
};
template <typename vector_type>
class LocalSpace : public boost::mpl::if_c<
                                                            VectorInfo<vector_type>::dim == 3,
                                                            LocapSpace3DBase<vector_type>,
                                                            BlankType>::type

有没有办法,摆脱的空白类型?像-如果维度是3,从3DBase派生,如果不是,什么都不做(而不是从空结构体派生)?

可以使用mpl::if_或mpl::if_c从不同的基类派生。在3d的分支中,您可以声明仅用于3d case的成员和方法。

像这样:

class LocalSpaceBase2
{
    vector_type m_up;
    // ...
};
template <typename vectortype>
class LocalSpace : public boost::mpl::if_c<
                              boost::is_same<vectortype, Vec3>,
                              LocalSpaceBase3,
                              LocalSpaceBase2>::type
{
    ...

boost::enable_if<>就是为这种情况设计的

是:如果你专门化模板,你必须专门化整个模板。

然而,有一个更简单的解决方案:只需将所有成员,甚至是3d特定的成员,放入主模板中,然后将static_assert s添加到3d特定成员中,以确保它们仅用于3d向量。

这不是一个特别可扩展的解决方案,但如果您只有一个或两个专门化,它是直接的,如果您需要更大的灵活性,它很容易重构。