首页 > 解决方案 > 将预增量结果转换为无效的原因

问题描述

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;
}

为什么++icast to的结果是void?是因为我们放弃了++i抑制可能的编译器警告的结果吗?如果是这样,为什么++first不也投射到void?因为operator ,隐式丢弃它?

标签: c++

解决方案


++first, (void) ++i

首先,++first被评估,然后(void) ++i被评估。

当我还是一个 C++ 初学者时,我认为这是一些特殊的语法,可以让您在 for 循环的“增量”步骤中执行多个操作。然而实际上并没有这种特殊的语法。这里之所以可以采取两个动作,是因为逗号操作符用于将两个表达式组合成一个表达式。

由于逗号运算符是可重载的,并且std::for_each_n是一种通用算法,因此用户定义其第一个参数是InputIt类型的重载逗号运算符的可能性很小。这不是特别可能,但有可能。因此,为了保证我们只做++firstand then ++i,没有其他副作用,有必要强制使用内置的逗号运算符。这是通过将参数之一强制转换为来完成的void:您不能有void参数operator,(或任何其他函数),因此这可以防止调用任何用户定义的重载。


推荐阅读