为类重载`unsigned`说明符

时间:2013-06-17 18:36:17

标签: c++

我正在尝试定义自己的数据类型(称为sfloat),它类似于float,但使用不同数量的尾数位和指数位来更好地适应我的数据范围和精度。目标是定义一个可以替换现有应用程序中的float的新数据类型。到目前为止,一切都在进行,除了我无法覆盖或定义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 个答案:

答案 0 :(得分:7)

由于C ++ default-int用于签名,operator unsigned ()只是operator unsigned int ()的语法简写。用户定义的类型无法声明为signedunsigned

答案 1 :(得分:3)

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

另一方面,您可以通过定义名为sfloatunsigned_sfloat的类型进行伪造,这些类型之间定义了转换。然后你可以写

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

然后将转换运算符定义为

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

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

希望这有帮助!

答案 2 :(得分:1)

你可以用模板模拟这样的东西:

#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;
}

答案 3 :(得分:0)

尝试以下方法:

template<typename T>
struct Unsigned;

并使用它:

Unsigned<sfloat> usfloat

现在,您必须为Unsigned类型专门设置Float,但这应该是“Float的未签名版本”,而不是unsigned_sfloat类型。如果你在构建一个完整的类型库,你可能想要附加Unsigned<>,那么我只会为此烦恼。