How to guarantee order of argument evaluation when calling a function object?
c++, c++11
Solution
What about a silly wrapper class like this:
struct OrderedCall
{
template <typename F, typename ...Args>
OrderedCall(F && f, Args &&... args)
{
std::forward<F>(f)(std::forward<Args>(args)...);
}
};
Usage:
void foo(int, char, bool);
OrderedCall{foo, 5, 'x', false};
If you want a return value, you could pass it in by reference (you'll need some trait to extract the return type), or store it in the object, to get an interface like:
auto x = OrderedCall{foo, 5, 'x', false}.get_result();
Problem
The answers to the question on how to avoid undefined execution order for the constructors when using std::make_tuple led to a discussion during which I learned that the order of argument evaluation can be guaranteed for constructors: Using a braced-init-list the order is guaranteed to be left to right: ``` T{ a, b, c } ``` The expressions `a`, `b`, and `c` are evaluated in the given order. This is the case, even if the type `T` just has a normal constructor defined. Clearly, not everything called is a constructor and sometimes it would be nice to guarantee the order of evaluation when calling a function but there is no such thing as brace-argument-list to call function with a defined order of evaluation of their arguments. The question becomes: Can the guarantees to constructors be used to build a function call facility ("`function_apply()`") with an ordering guarantee for the evaluation of arguments? It is acceptable to require a function object being called.