How to define a larger decltype expression type

Suppose I have a function like this:

static const boost::int32_t SOME_CONST_VALUE = 1073741823; template<typename targetType, typename sourceType> targetType Convert(sourceType source) { typedef decltype(source * SOME_CONST_VALUE) MulType_t; //typedef boost::int64_t MulType_t; MulType_t val = (MulType_t)source * (MulType_t)SOME_CONST_VALUE; return val / (MulType_t)SOME_CONST_VALUE; } 

When I call this function as follows

 boost::int32_t i = std::numeric_limits<boost::int32_t>::max(); boost::int32_t k = Convert<boost::int32_t>(i); 

k is 1, due to overflow during multiplication. Dropping everything on boost::int64_t will produce the result I want. But I do not want to throw short or char in int64 value.
Therefore, I can use decltype to get the next larger type of expression.

+4
source share
2 answers

To do this, you need to make your own template specialization:

 template<typename tp> class bigger { } template class bigger<boost::int8_t> { typedef boost::int16_t type; } template class bigger<boost::int16_t> { typedef boost::int32_t type; } template class bigger<boost::int32_t> { typedef boost::int64_t type; } 

You can also make a macro if you don't like typing a lot:

 #define BIGGER(x, y) \ template \ class bigger<boost::int##x##_t> \ { \ typedef boost::int##y##_t type; \ } BIGGER(8, 16); BIGGER(16, 32); BIGGER(32, 64); 

and then use it like

 bigger<boost::int32_t>::type x; 
+7
source

Dani's answer has the right idea, but invents the wheel.
Boost.Integer was created to solve the problem of choosing an integer type .

 static const boost::int32_t SOME_CONST_VALUE = 1073741823; template<typename targetType, typename sourceType> targetType Convert(sourceType source) { typedef typename boost::int_t< 8 * sizeof( sourceType ) + 1 >::fast MulType_t; MulType_t val = static_cast<MulType_t>(source) * static_cast<MulType_t>(SOME_CONST_VALUE); return val / static_cast<MulType_t>(SOME_CONST_VALUE); } 

You will not only avoid the new code (and new errors), but you will also use the fastest type for the required operation. If the speed is not what you are after Boost.Integer can also choose the smallest type.

+6
source

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


All Articles