Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当只有少数成员不同时,是否有必要专门化整个班级?_C++_Templates_Metaprogramming_Traits - Fatal编程技术网

C++ 当只有少数成员不同时,是否有必要专门化整个班级?

C++ 当只有少数成员不同时,是否有必要专门化整个班级?,c++,templates,metaprogramming,traits,C++,Templates,Metaprogramming,Traits,我正在设计类,这对于2d和3d几乎是一样的,所以我尝试使用模板,将其创建为一个按向量类型(2d-od-3d)键入的类 有些方法和成员对于2d和3d非常相同 有些(但很少)方法略有不同,我在这里使用trait-请参见doSomething() 有些成员和方法适用于3d,但不适用于2d(上方向向量),这是我的问题 我可以通过完全的类专门化来解决这个问题,但是有没有其他方法,如何在不专门化整个类的情况下包含/排除这些成员 我有一个特点: template<typename T> struc

我正在设计类,这对于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 };
};
模板
结构向量信息{};
模板
结构矢量信息
{
枚举{dim=2};
};
模板
结构矢量信息
{
枚举{dim=3};
};
模板
结构向量维数
{
枚举{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
};
模板
类本地空间
{
公众:
////////////////////////////////////////
//二维和三维通用
常量向量类型&getSideVector()常量;
void setSideVector(const vector_type&s);
常量向量类型&getForwardVector()常量;
void setForwardVector(常量向量类型&f);
常量向量类型&getPosition()常量;
无效设置位置(常数向量_类型&p);
布尔是右手()常量;
//其他方法。。。
//////////////////////////////////////////
//仅适用于3D
const vector_type&getUpVector()const;
无效设置向量(常量向量_类型&u);
//2D和3D的几种不同方法之一
内联空隙剂量测定法(常数向量型和v型)
{
doSomethingImpl(v,向量维数);
}
受保护的:
void doSomethingImpl(常量向量类型和v,向量维度)
{
}
void doSomethingImpl(常量向量类型和v,向量维度)
{
}
私人:
向量类型m_side;//2d+3d
向量类型m_向前;//2d+3d
向量类型m_up;//仅限于3d
向量类型m_位置;//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
struct BlankType{};
模板
类LocapSpace3DBase
{
公众:
const vector_type&getUpVector()const;
无效设置向量(常量向量_类型&u);
私人:
向量型m_-up;
};
模板
类LocalSpace:public boost::mpl::if\u c<
矢量信息::dim==3,
LocapSpace3DBase,
BlankType>::类型

有没有办法摆脱空白类型?类似-如果维度为3,则从3DBase派生,如果不是,则不执行任何操作(而不是从空结构派生)?

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

但是,有一个更简单的解决方案:只需将所有成员,甚至是三维特定的成员,放入主模板中,然后向三维特定的成员添加
static\u assert
s,以确保它们仅用于三维向量


这不是一个特别可扩展的解决方案,但是如果您只有一个或两个专门化,那么它很简单,而且如果您需要更大的灵活性,以后重构也很简单。

您可以使用或从不同的基类派生。在3d分支中,您可以声明仅3d案例所需的成员和方法

大概是这样的:

class LocalSpaceBase2
{
    vector_type m_up;
    // ...
};

template <typename vectortype>
class LocalSpace : public boost::mpl::if_c<
                              boost::is_same<vectortype, Vec3>,
                              LocalSpaceBase3,
                              LocalSpaceBase2>::type
{
    ...
class LocalSpaceBase2
{
向量型m_-up;
// ...
};
模板
类LocalSpace:public boost::mpl::if\u c<
boost::是一样的,
LocalSpaceBase3,
LocalSpaceBase2>::类型
{
...

boost::enable_,如果
是专为这种情况设计的。

谢谢!我刚刚对它做了一点修改,效果很好!我使用了
vectorifo::dim==3
来代替
boost::is_same
,用于支持3D和2D的多种向量类型,而不仅仅是Vec3和Vec2。@relaxx:可能有办法,但我没有办法现在就看吧。哦,好吧,也许你可以对
LocapSpace3DBase
进行不同的专门化,这样就可以完全摆脱
if_c
?不过,这样你就需要重新设计你的代码了。