tower120
tower120

Reputation: 5265

C++ unary right fold vs unary left fold with comma operator

Why comma separated unary left fold produce the same result as the right one?

Live code

template<class ...Args>
void right_fold(Args... args){
    ((std::cout << args),...);
}

template<class ...Args>
void left_fold(Args... args){
    (...,(std::cout << args));
}

int main()
{
    right_fold(1,2,3,4);
    std::cout << std::endl;
    left_fold(1,2,3,4);
}

OUTPUT:

1234
1234

Shouldn't it be:

4321
1234

?

Upvotes: 8

Views: 1856

Answers (3)

llllllllll
llllllllll

Reputation: 16434

Because they are indeed the same thing:

((std::cout << 1, std::cout << 2), std::cout << 3), std::cout << 4;
std::cout << 1, (std::cout << 2, (std::cout << 3, std::cout << 4));

Both have output 1234.

Upvotes: 4

user743382
user743382

Reputation:

Left vs right folding is the difference between ((a,b),c) and (a,(b,c)), but they have exactly the same effect when the built-in , operator is used: they first evaluate a, then b and finally c. To see a difference, you'd need to use a type with a custom overloaded , operator.

The syntax may look as if it would reverse the arguments, but no, that won't happen.

Upvotes: 13

Quentin
Quentin

Reputation: 63154

These folds respectively expand to:

((std::cout << 1), ((std::cout << 2), ((std::cout << 3), (std::cout << 4))))

... and:

((((std::cout << 1), (std::cout << 2)), (std::cout << 3)), (std::cout << 4))

Despite the flurry of parentheses, they are equivalent in terms of order of execution: left to right.

Upvotes: 4

Related Questions