C++20 之前向下转换到有符号数无法表示时是实现定义
什么是向下转换
向下转换是可能出现溢出的转换。检查是否为向下转换:
template <typename To, typename From, typename = void>
struct NotNarrowing: std::false_type {};
template <typename To, typename From>
struct NotNarrowing<To, From, std::void_t<decltype(To{std::declval<From>()})>>: std::true_type {};
其中 To{std::declval<From>()}
这一步如果用在具体的类型上(比如说 int 和 unsigned),编译器是只给警告,不会报错。如果能够在编译期推导出来数值,则会根据数值来选择通过或报错。比如 char{'a'};
是正常编译的,但是 char{300};
是会报错的。
向下转换溢出的判断标准是真实的表数范围:
- 无符号数和对应的有符号数互转都算是溢出。
- 范围较小的无符号数转向范围较大的有符号数是不溢出的。
- 任何有符号数转向无符号数都会溢出,因为无符号数不能表示负数。