这是一个使用一点 C++11 的版本。如果您无权访问constexpr
,则可以将其删除。如果您无权访问std::make_unsigned
,则可以实现自己的。如果您没有std::enable_if
,您也许可以使用 Boost(或自己制作)。它适用于有符号和无符号类型,以及正值和负值。更新:更新以使用浮点类型(以及浮点到整数,反之亦然)。
#include <type_traits>
// From integer type to integer type
template <typename to, typename from>
constexpr typename std::enable_if<std::is_integral<from>::value && std::is_integral<to>::value, to>::type
narrow_cast(const from& value)
{
return static_cast<to>(value & (static_cast<typename std::make_unsigned<from>::type>(-1)));
}
// For these next 3 versions, you'd be best off locally disabling the compiler warning
// There isn't much magic you can do when floating point types get invovled
// From floating point type to floating point type
template <typename to, typename from>
constexpr typename std::enable_if<std::is_floating_point<from>::value && std::is_floating_point<to>::value, to>::type
narrow_cast(const from& value)
{
// The best you can do here is a direct cast
return static_cast<to>(value);
}
// From integer type to floating point type
template <typename to, typename from>
constexpr typename std::enable_if<std::is_integral<from>::value && std::is_floating_point<to>::value, to>::type
narrow_cast(const from& value)
{
// The best you can do here is a direct cast
return static_cast<to>(value);
}
// From floating point type to integer type
template <typename to, typename from>
constexpr typename std::enable_if<std::is_floating_point<from>::value && std::is_integral<to>::value, to>::type
narrow_cast(const from& value)
{
// The best you can do here is a direct cast
return static_cast<to>(value);
}