0

The below demo prints 21 instead of 12. Why?

#include <iostream>
template<class... F> void callMany(F... fib){
    [&](...){}(
        (fib(),123)... 
    );
}
int main()
{
    auto f1=[&](){std::cout<<"1";};
    auto f2=[&](){std::cout<<"2";};
    callMany(f1,f2);
}

I tested it with both vc++ and g++. Both result are the same.

Is it a standard behavior? If so, which rules, and why?
Does it depend on compiler?

There is a way to reverse it, but I think it is a bit unrelated.

cppBeginner
  • 1,114
  • 9
  • 27

1 Answers1

3

When an expression that contains a pack expansion is evaluated, the pack is expanded first---which simply instantiates the code, so to speak, without performing any evaluation---then the resulting expression is evaluated according to the usual rules. Your expression

[&](...){}(
    (fib(),123)... 
);

is expanded into

[&](...){}(
    (f1(),123), (f2(),123)
);

and since function arguments are evaluated in an unspecified order, you cannot rely on f2 being called before f1 or vice versa.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312