The brace initialization (or uniform init) really is confusing. What exactly happens when a function returns a list of arguments in braces?
std::vector<double> foo()
{
//is this the same as: std::vector<double>{1, 2}
//or std::vector<double>(1, 2)?
//or something else?
return {1, 2};
}
return {1, 2};
, the return value is list-initialized from {1, 2}
, as the effect, the returned std::vector<double>
contains 2 elements with value 1
and 2
.
return std::vector<double>{1, 2};
, the return value is copy-initialized from std::vector<double>{1, 2}
, as the effect, the returned std::vector<double>
contains 2 elements with value 1
and 2
. In concept it'll construct a temporary std::vector<double>
and the return value is copy-initialized from the temporary; because of mandatory copy elision (since C++17) the copy/move operation is ommitted and the effect is exactly the same as the 1st case.
return std::vector<double>(1, 2)
, the return value is copy-initialized from std::vector<double>(1, 2)
, as the effect, the returned std::vector<double>
contains 1 elements with value 2
. Mandatory copy elision takes effect in this case too.