重载类的' unsigned '说明符

Overload `unsigned` specifier for classes

本文关键字:说明符 unsigned 重载      更新时间:2023-10-16

我试图定义我自己的数据类型(称为sfloat),它类似于浮点数,但使用不同数量的尾数位和指数位,以更好地适应我的数据范围和精度。我们的目标是定义一种新的数据类型,可以替换现有应用程序中的float。到目前为止,一切都解决了,只是我无法重写或定义unsigned操作符,以便

unsigned sfloat(3.141527)

将返回这个类的无符号版本usfloat(3.141527)

似乎unsigned说明符可能可以被重载,因为VS智能感知在头文件中没有抱怨:

sfloat::sfloat(float f) { m_data = get16bit(f); }
operator unsigned() { /*Do stuff here */ };

但是在声明和初始化中不起作用:

unsigned sfloat myPi= 3.141527; // Error: expected a ';'

我甚至不知道这在c++中是否可能做到,我很好奇以前是否有人这样做过?

由于c++默认为int表示签名,operator unsigned ()只是operator unsigned int ()的语法简写。用户定义的类型不能声明为signedunsigned

没有直接的方法可以完成你想要做的事情。正如@Angew在他的回答中提到的,unsigned不能应用于用户定义的类型。

另一方面,您可以通过定义名为sfloatunsigned_sfloat的类型来实现这一点,它们之间定义了转换。然后你可以写

unsigned_sfloat x(137.0f); // Close enough. ^_^

然后定义一个转换操作符

operator unsigned_sfloat() {
    ... implementation here ...
}

这给了你一些语法上接近你想要的东西,并解决了语言不允许你使用unsigned关键字来修改自定义类型的事实。

希望这对你有帮助!

你可以用模板模拟如下:

#include <type_traits>
template <typename T = int>
class myfloat
{
    static_assert(std::is_same<T, int>::value, "myfloat should only be instantiated on "signed" and "unsigned" ints");
    const bool isSigned = true;
    // the rest of the signed implementation  
};
template <>
class myfloat<unsigned>
{
    const bool isSigned = false;
    // the rest of the unsigned implementation  
};
int main()
{
    myfloat<> a;           // signed  
    myfloat<signed> b;     // signed  
    myfloat<unsigned> c;   // unsigned  
    // myfloat<float> d; // <-- compile error
    return 0;
}

尝试如下:

template<typename T>
struct Unsigned;

,像这样使用

Unsigned<sfloat> usfloat

现在,您必须为类型Float专门化Unsigned,但这应该比unsigned_sfloat类型更好地传达"是Float的无符号版本"。但是,如果您想要将Unsigned<>附加到这样的类型的整个库中,我才会这样做。