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.

Original source

Related problems