Overriding the `unsigned` qualifier for classes

I am trying to define my own data type (called sfloat ), similar to float, but using a different number of mantissa bits and exponential bits to better match the data range and accuracy. The goal is to define a new data type that can replace float in existing applications. Everything still works, except that I could not override or define the unsigned operator in such a way that

 unsigned sfloat(3.141527) 

will return an unsigned version of this class, usfloat(3.141527) .

It seems that the unsigned specifier may be overloaded, since VS intellisense does not complain in the header file:

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

But it does not work in declaration and initialization:

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

I don’t even know if it is possible to do this in C ++, and I wonder if someone has done this before?

+6
source share
4 answers

Thanks to C ++, default-int for signing operator unsigned () is just a syntactical shorthand for operator unsigned int () . Custom types cannot be declared signed or unsigned .

+7
source

There is no direct way to accomplish what you are trying to do. As @Angew said in his answer, unsigned cannot be applied to user types.

On the other hand, you can fake this by defining types with the names sfloat and unsigned_sfloat , in which conversions between them were defined. Then you could write

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

And then define the conversion operator as

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

This gives you something syntactically close to what you want, and works around the fact that the language does not allow you to use the unsigned keyword to change a custom type.

Hope this helps!

+3
source

You can do something like templates:

 #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; } 
+1
source

Try the following:

 template<typename T> struct Unsigned; 

and use it like:

 Unsigned<sfloat> usfloat 

Now you need to specialize Unsigned for your type of Float , but this should say "this is an unsigned version of Float " a little better than the type unsigned_sfloat . I would just bother with this, if you are building a whole library of these types, you might want to attach Unsigned<> to.

0
source

Source: https://habr.com/ru/post/947496/


All Articles