在C ++ 11中,如何实现适合内置类型层次结构的算术类型?

时间:2015-06-21 12:26:17

标签: c++ c++11 std

基本上,我想要实现float16类型。但是这个问题不是关于如何做到这一点的细节,而是如何设置,以便我的新float16类型适当地使用float,double和所有整数类型。

我希望我的float16类型可以类似地转换为float或double。例如,它应该隐式地转换为这两种类型。它也应该有std :: common_type(http://en.cppreference.com/w/cpp/types/common_type)类似于它的行为,因为std :: common_types对其他float类型的行为。这意味着std::common_type<my_float16, float>::type = floatstd::common_type<my_float16, double>::type = doublestd::common_type<my_float16, T>::type = my_float16其中T是任何整数类型。

我需要编写哪些构造函数和强制转换操作符才能使其工作?任何帮助将不胜感激!

我的other recent question可能是相关的。

编辑:好的,我已经建立了像安东这样的最小例子。它是

struct float16 {
    explicit operator int() {
        return 0;
    }

    operator float() {
        return 0.0f;
    }
};

这对于float和float16有正确的公共类型,但int和float16的公共类型仍然是int。我不明白。

3 个答案:

答案 0 :(得分:4)

我认为你不能完全理解这一点,因为C ++核心语言将本地定义的转换(例如char转换为int)与用户定义的转换(即使它们是隐式的)不同。

例如在

之后
struct float16 { float16(int) {} }; // cast int->float16 is implicit

struct Foo { Foo(const double&){} };  // constructor accepts a double&
struct Bar { Bar(const float16&){} }; // constructor accepts a float16&

void foo(const Foo&) {}
void bar(const Bar&) {}

调用foo(3)有效,因为整数3可以隐式转换为doublefoo接受可以隐式构建的Foo实例来自double的用户定义转换(Foo构造函数不是explicit)。

bar(3) 有效,因为此类调用需要两次隐式的用户定义转换(intfloat16float16Bar)这是不允许的。

答案 1 :(得分:2)

如果将其实现为struct / class类型,请提供所有相关运算符和构造函数的重载。如果类支持转换为其他类型的转换,请查找类所需的指南。

如果您希望自己的课程能够很好地使用std::common_typestd::numeric_limits等标准模板,则需要对这些模板进行适当的专业化。最好阅读这些专业要求描述的实际标准,但可能有一些教程材料(我已经看到了专门用于std::numeric_limits的良好介绍材料,但没有用于std::common_type

除非您使用特定于编译器的类型,否则对于内置标准类型(intfloat等)的类型将始终存在一些限制。

答案 2 :(得分:0)

我将自己回答这个问题。

我现在同意6502,我认为这不可能轻松实现。我发现这样做的唯一方法是为每种可能的类型组合提供操作符重载。这可以通过模板(和Boost运算符,http://www.boost.org/doc/libs/1_59_0/libs/utility/operators.htm稍微更好的方式完成,这是一个很好的例子),但这仍然是一个很好的工作和样板代码。