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