I call the std::pair<vector<int>, int> constructor two ways:
For some reason, the initializer list version makes a copy (and destroys one).
Here is my minimal code sample:
auto dummy() {
return pair<vector<int>, int>{ {1,2,3,4,5}, 1};
}
auto dummy1() {
return pair<vector<int>, int>{ vector{1,2,3,4,5}, 1};
}
auto dummy2() {
return optional<vector<int> > { {1,2,3,4,5} };
}
After checking the compiler explorer, I found that the initializer list dummy() version calls operator new twice, and delete once. This happens with neither the explicit construction version dummy1() nor a similar std::optional constructor in dummy2(). I wouldn't expect this behavior. Does anyone know why? I checked with clang as well.
The problem comes from std::pair constructors and template argument deduction / overload resolution:
pair( const T1& x, const T2& y ); // (1)
template< class U1, class U2 >
pair( U1&& x, U2&& y ); // (2)
Note that there is, at least, one "missing" constructor:
pair( T1&& x, T2&& y ); // (3)
When you use list-initialization for the first parameter, the selected constructor is not (2) (with U1 = std::initializer_list<int>) but (1)1. Thus, you need to construct a temporary std::vector<int>, which is passed as a const-reference to (1), which has to make a copy.
You can confirm empirically this by either:
pair with the third constructor mentioned above — in this case, (3) will be chosen, and the temporary vector will be moved;std::initializer_list<int> while constructing the std::pair: pair<vector<int>, int>{ std::initializer_list<int>{1,2,3,4,5}, 1 };
On the other hand std::optional as a single templated constructor:
template < class U = value_type >
constexpr optional( U&& value );
...but there is a default value for U, which makes this constructor a valid candidate for overload resolution.
1 When you call pair{ {1,2,3,4,5}, 1 }, U1 is in a non-deduced context within (2) [temp.deduct.type]#5.6, so deduction fails, which why (1) is selected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With