6

2 つの数値型Fromとが与えられますTo。次のコードは、情報を失うことなくFromtype の値を type の値として表すことができるかどうかを実際に判断しますか? Toはいの場合、より短い、またはより読みやすい決定方法はありますか?

template <class From, class To>
struct can_cast
{
    static const bool value = 
        (std::numeric_limits<From>::is_integer || // either From is an integer type OR 
        std::is_floating_point<To>::value) && // ...they're both floating point types AND
        (std::numeric_limits<From>::is_signed == false || // either From is unsigned OR
        std::numeric_limits<To>::is_signed == true) && // ...they're both signed AND
        (std::numeric_limits<From>::digits < std::numeric_limits<To>::digits || // To has more bits for digits than From OR
        std::numeric_limits<From>::digits == std::numeric_limits<To>::digits && // To and From have same number of bits, but
        std::numeric_limits<From>::is_signed == std::numeric_limits<To>::is_signed); // they're either both signed or both unsigned.
};
4

1 に答える 1

2

現在、コンパイラにはこの機能が組み込まれています。リストの初期化を使用する場合、縮小変換は許可されません。

に基づいて従来の式テスター トレイトを記述し、To { std::declval<From>() }場合によっては and を使用して追加のチェックを追加できstd::is_integralますstd::is_floating_point

template <typename T>
struct sfinae_true : std::true_type {};

struct can_cast_tester {
   template <typename From, typename To>
   sfinae_true<decltype(To { std::declval<From>() })> static test(int);
   template <typename...>
   std::false_type static test(...);
}; 

template <typename From, typename To>
struct can_cast // terrible name
: decltype(can_cast_tester::test<From, To>(0)) {};

理論的には、これは機能するはずですが、現在、GCC も clang も正しく動作していないようです。

于 2012-09-24T14:53:30.727 に答える