c++ - 确定数值类型 A 是否可以转换为数值类型 B

标签 c++ types casting c++11

给定两个数字类型FromTo。以下代码是否真的确定了 From 类型的任何值是否可以表示为 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.
};

最佳答案

编译器现在内置了这个功能:使用列表初始化时不允许缩小转换。

您可以根据 To { std::declval<From>() } 编写传统的表达式测试器特征并可能添加额外的检查 std::is_integralstd::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 都做不到。

关于c++ - 确定数值类型 A 是否可以转换为数值类型 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12567335/

相关文章:

java - 通过 jni 将每个引用的参数从 C++ 传递到 Java

types - 我什么时候应该在普通元组上使用元组结构?

c++ - 我们真的 grep c++​​ 风格转换吗?

c++ - 在 Windows 中检测 DVD 刻录机

c++ - 构建 obj 和 exe 文件的最佳目录结构是什么?

c++ - 在QWidget的setIcon方法中使用系统图标

struct - 指向结构 slice 的预期指针

types - 在 F# 中实现包含元素的队列类型

c++ - 如何将 Windows SOCKADDR_BTH 的 C++ 转换复制到 Rust 中的 SOCKADDR?

c - 类型转换为其中包含另一个结构 ptr 的结构