Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine a larger type of a decltype expression

Tags:

c++

c++11

Assume 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 like this

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

k equals 1, because of the overflow during the multiplication. Casting everything to boost::int64_t will lead to the result I want. But I don't want to cast a short or char to a int64 value.
So can I use the decltype to get the next larger type of the expression.

like image 484
mkaes Avatar asked Nov 21 '11 16:11

mkaes


1 Answers

You have to make your own specialization of a template for that:

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 alot:

#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;
like image 84
Dani Avatar answered Sep 28 '22 07:09

Dani