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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.