C++语义类型包装

Jur*_*aho 6 c++ overloading

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

struct Position: public Vector3 {
    using Vector3::Vector3;
};
Run Code Online (Sandbox Code Playgroud)

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

seh*_*ehe 5

考虑使用标签结构

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;
Run Code Online (Sandbox Code Playgroud)

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

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

//      template <typename OtherTag>
//            operator Vector3<OtherTag>() const { return /* ... */ }
    };
Run Code Online (Sandbox Code Playgroud)

如果您喜欢危险地生活,可以删除explicit关键字,或启用隐式转换运算符.这将具有能够启用混杂的运营商解决方案的"好处",如下所示:

 Position pos;
 Direction dir;
 Generic gen;

 dir = gen + pos; // you see why I call it 'promiscuous'?
Run Code Online (Sandbox Code Playgroud)

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

 Position operator+(const Position& v, const Translation& d) { /* .... */ }
Run Code Online (Sandbox Code Playgroud)

这样,您的类模型反映了类的语义.

C++ 0x可能包含启用显式转换运算符的东西,IIRC:

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