c-如何创建行为与其他类型相同的类型?

这个问题是由preferred mechanism to attach a type to a scalar?引起的,但是与度量单位有点偏离了轨道…

假设我要创建一个Float,它的工作原理几乎与float相同(在C#System中不一定是基本的.Float与float几乎完全相同;唯一的区别是一个是类型名,另一个是类型名)是一个关键字).

您可以从struct Float final {float v; } ;.然后可能会增加一堆运算符重载

inline auto operator+(Float lhs, Float rhs) {
    return Float { lhs.v + rhs.v };
}
// ... and so on ...
inline bool operator<(Float lhs, Float rhs) {
    return lhs.v < rhs.v;
}
// ... etc. ...

现在,我需要能够将Float转换为Double

struct Double final { double v; };  
struct Float final { float v;
    operator Double() const { return Double { v }; }
};

现在也许我添加了operator&(),以便可以更轻松地与旧版代码进行交互

extern void foo(const float*);
const Float f { 3.14 };
foo(&f);

而不是写foo(& f.v).

清单继续进行……然后,我意识到此代码对于Float和Double是相同的,因此我使用了模板:

template<typename T>
struct Type final { T v; }
using Float = Type<float>;
using Double = Type<double>;

但是现在我意识到T可能不像float那样便宜地复制,所以我必须更改重载

template<typename T>
inline auto make_Type(T&& v) {
    return Type<T> { std::forward<T>(v); }
}

template<typename T1, typename T2>
inline auto operator+(const Type<T1>& lhs, const Type<T2>& rhs) {
   return make_Type(lhs.v + rhs.v);
}

任意T会带来更多的复杂性.例如,它可能是可移动的,但不可复制.

是否有“规范”的方式来做这样的事情?还是真的开始变得(非常)混乱?以某种方式限制T是否有帮助? (我实际上只需要double,int等,而不需要std :: string或std :: vector< T>).也许有人已经使它适用于一切(差不多?)?

记住,最终我真的想要

template<typename T, typename Tag>
struct TaggedType final
{
typedef Tag tag_type;
typedef T value_type;
value_type value;
};

但不处理Tag似乎是一个很好的简化(并且避免了单位的麻烦).

解决方法:

您正在寻找的库最近在“ Standard C”站点上显示.

查看Tutorial: Emulating strong/opaque typedefs in C++

上一篇:如果超过24小时,则Mysql的“时间”类型会在Rails中给出“ ArgumentError:参数超出范围”


下一篇:有一种优雅的方式来表示包含C中不同类型的地图吗?