c++expressionstandardsvoid

Why use `(void)++p` rather than just `++p` in this C++ standard proposal?


In a C++ standard proposal, I find a strange code snippet as follows:

template <input_iterator I, sentinel_for<I> S, nothrow_forward_iterator I2>
constexpr auto uninitialized_copy(I first, S last, I2 d_first) -> I2 {
    using T = iter_value_t<I2>;
    I2 current = d_first;
    try {
        for (; first != last; ++first, (void)++current) {
            ::new (std::addressof(*current)) T(*first);
        }
    } catch (...) {
        std::destroy(d_first, current);
        throw;
    }
}

Why use (void)++current rather than just ++current here?


Solution

  • ++first, (void)++current uses the comma operator ,.

    If ++first evaluates to a type T and ++current to a type U and there is a operator, overload viable for T/U arguments, then this would call this operator, overload.

    However, it is not intended for it to be called. By making one of the two operands have type void, it becomes impossible that an overload of , will be chosen and it will instead always have the built-in meaning.

    That's why generic library code should always cast at least one operand to void when using the comma operator.