Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reason for casting preincrement result to void

Tags:

c++

cppreference gives the following code for a possible for_each_n implementation:

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

Why is the result of ++i cast to void? Is it because we discard the result of ++i to suppress the possible compiler warning? If so, why is the ++first not cast to void as well? Because operator , implicitly discards it?

like image 611
lukeg Avatar asked Dec 23 '22 18:12

lukeg


1 Answers

In

++first, (void) ++i

first, ++first is evaluated, and then (void) ++i is evaluated.

When I was a C++ beginner I thought this was some special syntax that lets you perform multiple actions during the "increment" step of a for loop. However there is in fact no such special syntax. The reason why two actions can be taken here is that the comma operator is used to combine two expressions into a single expression.

Since the comma operator is overloadable, and std::for_each_n is a generic algorithm, there is a small chance that the user has defined an overloaded comma operator whose first argument is the InputIt type. This isn't particularly likely, but it is possible. So, in order to guarantee that we simply do ++first and then ++i, with no other side effects, it's necessary to force the built-in comma operator to be used. This is done by casting one of the arguments to void: you cannot have a void argument to operator, (or any other function) so this prevents any user-defined overloads from being called.

like image 59
Brian Bi Avatar answered Dec 29 '22 00:12

Brian Bi