Is it necessary to specialize whole class, when differs just with few members?
我正在设计类,这对于2d和3d几乎是相同的,所以我尝试使用模板,以将其创建为按矢量类型(2d od 3d)键入的一个类。
2d和3d的某些方法和成员非常相同
一些(但很少)方法略有不同,我在这里使用特征-请参见
有些成员和方法适用于3d,但不适用于2d(向上矢量),这是我的问题。
我可以通过完全的类专门化来解决它,但是还有其他方法,如何在不专门化整个类的情况下包括/排除这些成员?
我有特质:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 }; }; |
和班级:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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 }; |
希望你理解我的问题。
编辑:
谢谢您的反馈,
我现在有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
有什么办法可以摆脱BlankType? 像-如果尺寸为3,则从3DBase派生,如果不是,则不做(而不是从空结构派生)?
您可以使用mpl :: if_或mpl :: if_c从不同的基类派生。 在3d分支中,您可以声明仅3d情况所需的成员和方法。
像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class LocalSpaceBase2 { vector_type m_up; // ... }; template <typename vectortype> class LocalSpace : public boost::mpl::if_c< boost::is_same<vectortype, Vec3>, LocalSpaceBase3, LocalSpaceBase2>::type { ... |
是的:如果您专门化模板,则必须专门化整个模板。
但是,有一个更简单的解决方案:只需将所有成员(甚至是3-D特定的成员)放入主模板中,然后将
这不是一个特别可伸缩的解决方案,但是如果您只有一个或两个专业,那么它很简单,并且如果需要更大的灵活性,以后可以很容易地进行重构。