c++ - 将预增量结果转换为无效的原因
问题描述
cppreference为可能的for_each_n
实现提供了以下代码:
template<class InputIt, class Size, class UnaryFunction>
InputIt for_each_n(InputIt first, Size n, UnaryFunction f)
{
for (Size i = 0; i < n; ++first, (void) ++i) {
f(*first);
}
return first;
}
为什么++i
cast to的结果是void
?是因为我们放弃了++i
抑制可能的编译器警告的结果吗?如果是这样,为什么++first
不也投射到void
?因为operator ,
隐式丢弃它?
解决方案
在
++first, (void) ++i
首先,++first
被评估,然后(void) ++i
被评估。
当我还是一个 C++ 初学者时,我认为这是一些特殊的语法,可以让您在 for 循环的“增量”步骤中执行多个操作。然而实际上并没有这种特殊的语法。这里之所以可以采取两个动作,是因为逗号操作符用于将两个表达式组合成一个表达式。
由于逗号运算符是可重载的,并且std::for_each_n
是一种通用算法,因此用户定义其第一个参数是InputIt
类型的重载逗号运算符的可能性很小。这不是特别可能,但有可能。因此,为了保证我们只做++first
and then ++i
,没有其他副作用,有必要强制使用内置的逗号运算符。这是通过将参数之一强制转换为来完成的void
:您不能有void
参数operator,
(或任何其他函数),因此这可以防止调用任何用户定义的重载。
推荐阅读
- autocomplete - 谷歌表格中的自动填充词
- c++ - 要从 Delphi 调用的 C++ dll 函数 - 数组参数
- intellij-idea - Intellij 的想法。javax.net.ssl.SSLHandshakeException:没有合适的协议(协议被禁用或密码套件不合适)
- php - 网页被封锁!从数据发送 POST 中的 URL 时
- awk - 不要在 awk 中转义变量
- node.js - 如何停止接收有关主题的 kafka-metadata 消息
- android - 数据绑定:如何在一个视图中绑定不同的数据变量
- excel - 数据透视表 Excel 到 Google 表格在列上添加计算值
- xaml - UWP 社区工具包 DataGrid:无法声明列
- php - 在php中用单引号连接变量