有没有"safe" static_cast选择?
Is there a "safe" static_cast alternative?
在 C++11/14 或实现此功能的库中是否有"安全"的替代方案来替代static_cast
?
我所说的"安全"是指铸件应该只允许不会失去精度的铸件。因此,仅当数字适合int32_t
并且报告错误时,才允许从int64_t
转换为int32_t
。
有gsl::narrow
窄//如果
static_cast<T>(x) == x
narrow<T>(x)
static_cast<T>(x)
,否则会抛出narrowing_error
用例颠倒过来了。
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
通常只会导致警告(,因此请确保使用正确的标志来强制将警告视为错误。
假设问题是关于潜在有损转换的编译时检测......
这里还没有提到的一个简单的工具是列表初始化不允许缩小范围,所以你可以写:
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
}
仅当您强制转换为的大小为>= 源大小时,才会编译。
在这里尝试一下
您可以使用其他类型和type_traits的numeric_limits使情况进一步复杂化。
请注意,我的解决方案是编译时解决方案,因为您询问了static_cast
,其中 static 在这里指的是"在编译时确定"。
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何理解C++标准N3337中的expr.const.cast子句8
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- QTreeView幻灯片多选后无法使用单击选择
- 无法获取菜单选择以运行函数.C++
- C++Cast运算符过载
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 在C++中,如何通过几种类型从元组中选择多个元素
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 对可变参数使用声明.如何选择正确的功能
- 选择选举获胜者的程序
- 如何选择在 csv 文件中输出的位置
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 选择和修改嵌套向量中的条目的最佳实践
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"