C ++语义类型包装

时间:2011-06-17 08:08:25

标签: c++ overloading

我有一个数据类型,例如class Vector3。现在我需要创建几个与Vector3具有相同接口的类,但具有更高级别的语义(例如:PositionVelocity)。使用typedef是不够的,因为我需要这些类型是不同的,以便它们可以用于重载。在C ++ 0x中,我可能使用构造函数继承:

struct Position: public Vector3 {
    using Vector3::Vector3;
};

这有什么问题吗?有没有更好的方法呢?是否可以在不使用C ++ 0x功能的情况下执行此操作,而不必显式编写所有Vector3构造函数?

2 个答案:

答案 0 :(得分:5)

考虑使用标签struct

struct tagPosition {};
struct tagDirection {};
struct tagGeneric {};

namespace detail
{
    template <typename Tag=tagGeneric>
        class Vector3
    {
        // business as usual
    };
}

typedef detail::Vector3<tagPosition>  Position;
typedef detail::Vector3<tagDirection> Direction;
typedef detail::Vector3<tagGeneric>   Vector3;

对于奖励积分,有转换运算符/构造函数:

    template <typename Tag=tagGeneric>
        class Vector3
    {
        template <typename OtherTag>
            explicit Vector3(const Vector3<OtherTag>& rhs) { /* ... */ }

//      template <typename OtherTag>
//            operator Vector3<OtherTag>() const { return /* ... */ }
    };

如果您想生活危险,可以删除explicit关键字,或启用隐式转换运算符。如果能够启用 混杂 运营商解决方案,这将具有“好处”:

 Position pos;
 Direction dir;
 Generic gen;

 dir = gen + pos; // you see why I call it 'promiscuous'?

我建议(相反)为这样的情况定义显式运算符(自由函数:)

 Position operator+(const Position& v, const Translation& d) { /* .... */ }

这样你的类模型就会反映你的类的语义。

C++0x would possibly contain things to enable explicit conversion operators,IIRC:

  

在转换构造函数的情况下,可以通过将构造函数声明为显式来禁用隐式转换。N1592 proposal将此关键字的语义拉伸到所有转换运算符。声明为explicit的转换运算符不会执行隐式转换。相反,程序员必须明确地调用它

答案 1 :(得分:4)

当我需要不同但相似的类型时,我通常使用虚拟模板参数,例如(关闭袖口,不受编译器脏手的影响)

template< class UniqueId >
struct Blah {};

typedef Blah< struct AlphaId > Alpha;
typedef Blah< struct BetaId > Beta;

这可能是您需要的也可能不是。

干杯&amp;第h。,