Why do I not get guaranteed copy elision with std::tuple?
When constructing std::tuple<int, INeedElision>
from {i, {47}}
, the selected constructor of std::tuple
takes elements by lvalue-reference to const
.
tuple( const Types&... args );
Then when use {i, {47}}
as the initializer, a temporary INeedElision
will be constructed and then passed to the constructor of std::tuple
(and get copied). The temporary object will be destroyed immediately and you'll see "Bye" between "A" and "B".
BTW: The 3rd constructor of std::tuple
won't be used for this case.
template< class... UTypes > tuple( UTypes&&... args );
It's a constructor template, and braced-init-list like {47}
doesn't have type and can't be deduced by template argument deduction.
On the other hand, if INeedElision
has a converting constructor taking int
, and make the initializer as {i, 47}
, the 3rd constructor of std::tuple
will be used and no temporary INeedElision
is constructed; the element will be constructed in-place from the int
47
.