Typedefs equivalence detection

In my application, I have a type responsible for computing, which (may) include large numbers, and a type that is used for communication between processors.

typedef MyBigIntegerClass bigInt; typedef int smallInt; 

The communication part is not compatible with MyBigIntegerClass, therefore, before the message, for example, the vector bigInts, it must be converted to smallints. So far, no problem.

However, for most problematic cases, the use of MyBigIntegerClass is not required. In fact, even int32_t enough. This is why I allow configuration like

 typedef int32_t bigInt; typedef int16_t smallInt; 

The bigInt type is still large enough for computation. The problem is that smallInt should be different from bigInt.

 class Problematic { public: Problematic(bigInt); Problematic(smallInt); }; 

In this class, constructors or methods can either accept bigInts or smallInts. If they match, compilation fails.

Because other code users may want to adjust the types used, they may end up with a configuration such as

 typedef int32_t bigInt; typedef int32_t smallInt; 

and compilation is not performed in (at least for some developers) in an unobvious way.

One way to handle this would be static_assert(sizeof(bigInt) != sizeof(smallint), "bad config..") , but I really like the ability to have bigInt == smallInt . What would be a good way to modify a class Problematic declaration to allow type equivalence?

+4
source share
1 answer

If you want to save both constructors, a possible solution wraps int types in templates, which means that they are always different types, even if the base type int the same:

 template <typename T> struct big_int { T value; }; template <typename T> struct small_int { T value; }; typedef big_int<long> bigInt; typedef small_int<long> smallInt; class Problematic { public: Problematic(bigInt) {} Problematic(smallInt) {} }; 

Compiles when the base types are the same ( http://ideone.com/KGz9Vk ) and when they do not match ( http://ideone.com/Pt0XGS ).

To allow big_int<> and small_int<> to behave as integer types, operator implementations are required. For instance:

 template <typename T> struct big_int { T value; operator T() { return value; } big_int& operator+=(big_int const& other) { value += other.value; return *this; } template <typename U> big_int& operator+=(U const& v) { value += v; return *this; } big_int& operator++() { ++value; return *this; } big_int operator++(int) { big_int temp = *this; ++value; return temp; } }; 

This is not exhaustive (see http://herbsutter.com/2013/05/20/gotw-4-class-mechanics/ for useful recommendations on implementing operators). For example, http://ideone.com/xlE2Mi .

+2
source

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


All Articles