5

I am reading through Nicolai M. Josuttis' "The C++ Standard Library (Second Edition)" and have just reached the section on std::pair. The author notes that:

Since C++11, a pair<> using a type that has only a nonconstant copy constructor will no longer compile.

He then goes on to give the following example:

class A 
{
   public:
     ...
     A( A& ); // copy constructor with nonconstant reference
     ...
};

std::pair<A, int> p; // Error since C++11

However, I'm interested in the reason that the standards committee decided to make this amendment to the standard library standard? I tried to google the reason, but was unsuccessful in finding anything pertinent.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Thomas Russell
  • 5,870
  • 4
  • 33
  • 68
  • 1
    I would have to guess it was always meant to use const to promise to the user to preserve the contents of the pair, and C++11 was able to fit that in the actual standard. – Syntactic Fructose May 17 '13 at 19:35

1 Answers1

4

In C++98, copy constructors with non-constant reference parameters would be (ab)used to "move" elements around. Such code was notoriously unsafe and unclear. The infamous and now deprecated std::auto_ptr was the prime example of that.

In C++11, we have move semantics and rvalue references to achieve the same effects much more safely and clearly. This is because an rvalue reference is a reference to a mutable object, but it can only bind to "safe" expressions such as temporaries or things that you have explicitly cast (via std::move) and thus marked as disposable.

In short: classes with copy constructors taking non-reference members have no real use cases that cannot be done better and safer with rvalue references. std::pair acquired a move constructor std::pair(std::pair&&)=default to accomodate such semantics.

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304