This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.
Section: 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.
The FDIS version of the 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.
Unfortunately there seems to be no simple library solution for this problem. If the defaulted declarations were removed, both copy c'tor and move c'tor would be deleted, because there exist user-declared copy assignment and move assignment operators in the FDIS. But these operations need to be user-defined to realize the wanted semantics of these operations for element types that are reference types. If core rules would not be changed to fix that, I see the following options: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: