I am designing class, which is almost the same for 2d and 3d, so I am trying to use templates, to create it as one class typed by vector type (2d od 3d)
Some methods and member are very same for 2d and 3d
Some (but very few) methods are slightly different, I use trait here – see doSomething()
Some members and method are present for 3d but are not for 2d (up vector) and THAT IS MY PROBLEM.
I can solve it by complete class specialization, but is there any other way, how to include/exclude these members without specialization whole class?
I have trait:
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 };
};
and Class:
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
};
Hope you understand my question.
EDIT:
thank you for your responses,
now I have
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
Is there any way, to get rid of the BlankType? Like – if the dimension is 3, derive from 3DBase, if not, DO NOTHING (instead of derive from empty struct)?
You can derive from different base classes using mpl::if_ or mpl::if_c. In the branch for 3d you can declare the members and methods needed only for 3d case.
Something like this: