简体   繁体   中英

static_cast with bounded types

When you cast an int in short with a classic static_cast (or c cast), if the value is out of the short limits, the compiler will truncat the int.

For example:

int i = 70000;
short s = static_cast<short>(i);
std::cout << "s=" << s << std::endl;

Will display:

s=4464

I need a "inteligent" cast able to use the type limit and, in this case return 32767. Something like that:

template<class To, class From>
To bounded_cast(From value)
{
  if( value > std::numeric_limits<To>::max() )
  {
    return std::numeric_limits<To>::max();
  }
  if( value < std::numeric_limits<To>::min() )
  {
    return std::numeric_limits<To>::min();
  }
  return static_cast<To>(value);
}

This function works well with int, short and char, but need some improvments to works with double and float.

But is it not a reinvention of the wheel ?

Do you know an existing library to do that ?

Edit:

Thanks. The best solution I found is this one:

template<class To, class From>
To bounded_cast(From value)
{
  try
  {
    return boost::numeric::converter<To, From>::convert(value);
  }
  catch ( const boost::numeric::positive_overflow & )
  {
    return std::numeric_limits<To>::max();
  }
  catch ( const boost::numeric::negative_overflow & )
  {
    return std::numeric_limits<To>::min();
  }
}

Take a look at boost's Numeric Conversion library . I think you'll need to define an overflow policy that truncates the source value to the target's legal range (but I haven't tried it). In all, it may take more code than your example above, but should be more robust if your requirements change.

Read Boost numeric_cast<> with a default value instead of an exception? So question.

You can use std::numeric_list as your default value when an exception is thrown

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM