6

我正在尝试定义我自己的数据类型(称为sfloat),它类似于浮点数,但使用不同数量的尾数位和指数位以更好地适应我的数据范围和精度。目标是定义一种新的数据类型,可以替换现有应用程序中的浮点数。到目前为止一切正常,除了我无法覆盖或定义unsigned运算符

unsigned sfloat(3.141527)

将返回此类的未签名版本,usfloat(3.141527).

似乎说明unsigned可能会被重载,因为 VS intellisense 没有在头文件中抱怨:

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

但它不适用于声明和初始化:

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

我什至不知道这是否可以在 C++ 中完成,我很好奇之前是否有人这样做过?

4

4 回答 4

8

由于 C++ default-int 表示有符号,operator unsigned ()它只是operator unsigned int (). 用户定义的类型不能被声明signedunsigned.

于 2013-06-17T18:38:16.290 回答
4

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

另一方面,您可以通过定义类型命名sfloatunsigned_sfloat在它们之间定义转换来伪造这一点。然后你可以写

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

然后将转换运算符定义为

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

这为您提供了一些语法上接近您想要的内容,并解决了该语言不允许您使用unsigned关键字来修改自定义类型的事实。

希望这可以帮助!

于 2013-06-17T18:40:36.967 回答
2

你可以用模板模拟这样的事情:

#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;
}
于 2013-06-17T18:53:19.850 回答
0

尝试以下操作:

template<typename T>
struct Unsigned;

并像这样使用它:

Unsigned<sfloat> usfloat

现在,您必须专门Unsigned针对您的类型Float,但这应该传达“是一个无符号版本的Float”比类型稍好unsigned_sfloat。但是,如果您在哪里构建您可能想要附加的此类类型的整个库,我只会为此烦恼Unsigned<>

于 2013-06-17T18:48:28.320 回答