Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of Evaluation for Fold Expressions

Fold expressions seem to be a nice way to apply a function to each element of a tuple. However, if the applied function has side effects, the order of function invocations might be an important concern.

Consider:

#include <iostream>

template<typename... Ts>
void printStuff(Ts... args)
{
    ( ([](auto&& v) { std::cout << v << " "; })(args), ... );
    std::cout << '\n';
}

int main()
{
    printStuff("hello", 42, 1.5f);
    // expected output: hello 42 1.5
}

This seems to work.

But is the order of evaluation for the lambdas guaranteed here or could I end up with the values being flipped around in the output? Does the answer change if I used a different operator for chaining the commands together?

like image 924
ComicSansMS Avatar asked Sep 05 '17 13:09

ComicSansMS


People also ask

What is the order of evaluation?

Order of evaluation refers to the operator precedence and associativity rules according to which mathematical expressions are evaluated.

What is the order of evaluation in C programming language?

Only the sequential-evaluation ( , ), logical-AND ( && ), logical-OR ( || ), conditional-expression ( ? : ), and function-call operators constitute sequence points, and therefore guarantee a particular order of evaluation for their operands.

What is the evaluation order of the function parameters in C++?

The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. The same verbiage is used by C++14 standard as well, and is found under the same section. Save this answer.

Are IF statements evaluated left to right?

You can combine two or more conditional expressions on the IF statement. ISPF evaluates the conditional expressions on the IF statement from left to right, starting with the first expression and proceeding to the next and subsequent expressions on the IF statement until processing is complete.


1 Answers

A right-fold over an operator expands like this: ... (arg0 op (arg1 op arg2)). So while the parens help, they don't guarantee anything about the order of the individual elements.

Therefore, it's all left up to op. And the comma operator (which is distinct from commas separating function arguments), even pre-C++17, is a hard sequence point. It ensures left-to-right evaluation with no cross-talk.

If you had instead used +, there would be no sequencing guarantees. So it depends on the operator you use. C++17 added a few more operators that have strict sequencing guarantees (<<, for example).

like image 53
Nicol Bolas Avatar answered Sep 22 '22 01:09

Nicol Bolas