static_cast
在 C++11/14 或实现此功能的库中是否有“安全”替代方案?
通过“安全”,我的意思是演员应该只允许不失去精度的演员。因此,只有当数字适合 a 时才允许从int64_t
to转换,否则会报告错误。int32_t
int32_t
static_cast
在 C++11/14 或实现此功能的库中是否有“安全”替代方案?
通过“安全”,我的意思是演员应该只允许不失去精度的演员。因此,只有当数字适合 a 时才允许从int64_t
to转换,否则会报告错误。int32_t
int32_t
窄 //
narrow<T>(x)
是static_cast<T>(x)
ifstatic_cast<T>(x) == x
或者它抛出narrowing_error
您已经颠倒了用例。
(和其他 c++ 风格的强制转换)的预期用途static_cast
是表明程序员的意图。当你写的时候auto value = static_cast<int32_t>(value_64);
,你说的是“是的,我非常*打算*在我执行这个任务时降低这个值,可能会截断它”。结果,在正常情况下可能倾向于抱怨这种转换的编译器(例如,如果您已经int32_t value = value_64;
编写了大部头书?” 并将默默地编译代码。
如果您希望您的 C++ 代码在不安全的转换时发出警告或抛出错误,您需要明确不使用static_cast
, const_cast
, reinterpret_cast
,并让编译器完成其工作。编译器具有更改警告处理方式的标志(向下转换int64_t
为int32_t
通常只会导致警告),因此请确保您使用正确的标志来强制将警告视为错误。
假设问题是关于潜在有损转换的编译时检测......
这里还没有提到一个简单的工具是列表初始化不允许缩小,所以你可以写:
void g(int64_t n)
{
int32_t x{n}; // error, narrowing
int32_t g;
g = {n}; // error, narrowing
}
注意。某些默认模式下的编译器可能会显示“警告”并继续编译此格式错误的代码,通常您可以通过编译标志配置此行为。
您可以使用 sfinae 创建自己的。这是一个例子:
template <typename T, typename U>
typename std::enable_if<sizeof(T) >= sizeof(U),T>::type
safe_static_cast(U&& val)
{
return static_cast<T>(val);
}
int main()
{
int32_t y = 2;
std::cout << safe_static_cast<int32_t>(y) << std::endl;
std::cout << safe_static_cast<int16_t>(y) << std::endl; // compile error
}
仅当您转换为的大小 >= 源大小时才会编译。
在这里试试
您可以将numeric_limits用于其他类型和type_traits使这进一步复杂化。
请注意,我的解决方案是编译时解决方案,因为您询问过static_cast
,这里的 static 是指“在编译时确定”。