在C ++ 11/14中,是否有static_cast
的“安全”替代品或实现此功能的库?
“安全”是指演员表应只允许不损失精度的演员表。因此,只有在数字适合int64_t
且报告了错误的情况下,才允许从int32_t
到int32_t
的转换。
答案 0 :(得分:35)
缩小// //
@HostBinding
是narrow<T>(x)
,如果static_cast<T>(x)
或抛出static_cast<T>(x) == x
答案 1 :(得分:21)
您已经颠倒了用例。
static_cast
(和其他c ++样式强制转换)的预期用途是指示程序员的意图。当您写auto value = static_cast<int32_t>(value_64);
时,您是在说“是的,我非常想*贬低这个值,当我执行此分配时可能会截断它”。结果,通常情况下可能倾向于抱怨这种转换的编译器(例如,如果您编写了int32_t value = value_64;
)则观察到”,程序员告诉我这是他们的意图是什么;他们为什么对我说谎?” 并会静默地编译代码。
如果您希望C ++代码对不安全的转换发出警告或引发错误,则需要明确地不使用static_cast
,const_cast
,reinterpret_cast
,并让编译器完成工作。编译器具有更改警告处理方式的标志(将int64_t
转换为int32_t
通常只会产生警告),因此请确保使用正确的标志将警告视为错误。< / p>
答案 2 :(得分:0)
您可以使用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
}
仅当您投射到的尺寸> =源尺寸时,此选项才会编译。
尝试here
对于其他类型,您可以使用numeric_limits和type_traits将其进一步复杂化。
请注意,我的解决方案是编译时解决方案,因为您询问了static_cast
,此处的静态是指“在编译时确定”。
答案 3 :(得分:0)
假设问题是关于潜在损失转化的编译时检测...
这里尚未提及的一个简单工具是列表初始化不允许缩小,因此您可以编写:
void g(int64_t n)
{
int32_t x{n}; // error, narrowing
int32_t g;
g = {n}; // error, narrowing
}
NB。一些处于默认模式的编译器可能会显示“警告”,并继续对此格式错误的代码进行编译,通常您可以通过编译标志来配置此行为。