Ignoring the copy/move elision from the compiler, I would like to know if the following code (assuming foo has a constructor accepting three ints) "syntactically" creates a temporary object and then copy/move initializes the function argument, or directly calls the constructor:
void acceptsFoo(foo a);
acceptsFoo({1, 2, 3});
And what about this case?
//ignoring RVO optimization
foo returnsFoo()
{
return {1, 2, 3};
}
I know that the code below, even without copy/move elision, is the same as calling the constructor so will not generate any temporary, but I couldn't find info about the code above.
foo = { 1, 2, 3 } //assuming the constructor is non-explicit
foo { 1, 2, 3 }
When a braced-init-list is used to initialize an object, it is used to initialize the object. Period.
Applying a braced-init-list to a function parameter means to initialize that parameter with the list of values, in accord with the rules of list initialization. When you return a braced-init-list, it is used to initialize the return value object with the list of values, in accord with the rules of list initialization.
There is no temporary object theoretically being copied into the parameter/return value.
Now (pre-C++17), if you had done acceptsFoo(foo{1, 2, 3});
or return foo{1, 2, 3}
, then that would provoke the creation of a temporary, which would then be used to initialize the parameter/return value.