我有一个数据类型,例如class Vector3
。现在我需要创建几个与Vector3
具有相同接口的类,但具有更高级别的语义(例如:Position
,Velocity
)。使用typedef
是不够的,因为我需要这些类型是不同的,以便它们可以用于重载。在C ++ 0x中,我可能使用构造函数继承:
struct Position: public Vector3 {
using Vector3::Vector3;
};
这有什么问题吗?有没有更好的方法呢?是否可以在不使用C ++ 0x功能的情况下执行此操作,而不必显式编写所有Vector3
构造函数?
答案 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。,