基本上,我想要实现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 = float
,std::common_type<my_float16, double>::type = double
和std::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。我不明白。
答案 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
可以隐式转换为double
,foo
接受可以隐式构建的Foo
实例来自double
的用户定义转换(Foo
构造函数不是explicit
)。
但bar(3)
不有效,因为此类调用需要两次隐式的用户定义转换(int
→float16
和float16
→ Bar
)这是不允许的。
答案 1 :(得分:2)
如果将其实现为struct / class类型,请提供所有相关运算符和构造函数的重载。如果类支持转换为其他类型的转换,请查找类所需的指南。
如果您希望自己的课程能够很好地使用std::common_type
和std::numeric_limits
等标准模板,则需要对这些模板进行适当的专业化。最好阅读这些专业要求描述的实际标准,但可能有一些教程材料(我已经看到了专门用于std::numeric_limits
的良好介绍材料,但没有用于std::common_type
)
除非您使用特定于编译器的类型,否则对于内置标准类型(int
,float
等)的类型将始终存在一些限制。
答案 2 :(得分:0)
我将自己回答这个问题。
我现在同意6502,我认为这不可能轻松实现。我发现这样做的唯一方法是为每种可能的类型组合提供操作符重载。这可以通过模板(和Boost运算符,http://www.boost.org/doc/libs/1_59_0/libs/utility/operators.htm稍微更好的方式完成,这是一个很好的例子),但这仍然是一个很好的工作和样板代码。