C++ forcing function parameter evalution order
The semi-colon that separates statements imposes a "happens before" relation.
auto && a = increment()
must be evaluated first. It is guaranteed. The returned temporary will be bound to the reference a
(and its lifetime extended) before the second call to increment
.
There is no UB. This is the way to force an evaluation order.
The only gotcha here is if increment
returned a reference itself, then you'd need to worry about lifetime issues. But if there was no lifetime issues, say if it returned a reference to count
, there still would not be UB from the imposed evaluation of a
and then b
.
Here's another way to force the evaluation order, using a std::initializer_list
, which has a guaranteed left-to-right order of evaluation:
#include <numeric> // for accumulate
#include <initializer_list>
template <class T>
auto diff(std::initializer_list<T> args)
{
return std::accumulate(args.begin(), args.end(), T(0), std::minus<>{});
}
const auto result = diff({increment(), increment()});
This restricts you to objects of the same type, and you need to type additional braces.