std::pair
not C++03-compatible with defaulted copy c'torSection: 22.3.2 [pairs.pair] Status: NAD Submitter: Daniel Krügler Opened: 2011-06-18 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [pairs.pair].
View all other issues in [pairs.pair].
View all issues with NAD status.
Discussion:
The specification of the copy semantics of the C++03 version of std::pair
is defined by the class synopsis in [lib.pairs]:
template <class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(); pair(const T1& x, const T2& y); template<class U, class V> pair(const pair<U, V> &p); };
The effect of this specification is, that the copy constructor is compiler-declared
with the proper form depending on the contained member types. In particular, the
instantiation of pair
is well-formed with an element type that has a
copy constructor with non-const first parameter type like specialzations of auto_ptr
or any user-defined type like the following one:
struct A { A(A&){} };
In contrast to container types which require CopyConstructible
value types, the C++03 pair
does support these, albeit unusual, element types.
std::pair
specification does specify the same semantics by
defaulting the copy and move constructor in 22.3.2 [pairs.pair]:
template <class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(const pair&) = default; pair(pair&&) = default; pair(); […] };
But according to the current core rules this makes the instantiation of e.g. std::pair<A, int>
ill-formed, because of the const
mismatch of the compiler-declared form of the copy constructor
with that of the defaulted declaration.
pair
.pair
specializations,
but this would still not allow to copy them by the copy constructor.pair
specializations and of these members. This would
support all element types as it did in C++03, but all copy/move members would be non-trivial.pair
, but
still keep the allocator support with the effect of removing all declarations of the special
copy/move members. User code that needs to use tuple
instead. But this would be a rather
drastic step requiring further corrections of the draft, e.g. a change of the signature of the algorithm
minmax
(not the overload with the initializer_list
) with a different return type.
This problem does not extend as backward-compatibility problem to tuple
, because the TR1
specification did explicitly declare copy constructor and copy assignment operator via the "normal"
form:
tuple(const tuple&); tuple& operator=(const tuple&);
[Bloomington, 2011]
Closed as NAD.
This is an unfortunate change of behavior between C++03 and C++11, but is consistent with tuple
. There is no desire to go to lengths supporting types like auto_ptr
now that rvalue references are in the language.
There may be an issue for Core/EWG to look at, so that some simple =default
syntax could be used that would do the right thing. If such a facility became availabile, LWG might revisit this issue.
Proposed resolution: