1
votes

I am reading Josuttis` C++ standard library. I could not find the reasoning for the (2) and (3) comments on following example:

D d;  //instance of the deleter type(1)
unique_ptr<int,D> p1(new int, D()); //D must be  MoveConstructible(2)
unique_ptr<int,D> p2(new int, d);  //D must be CopyConstructible(3)

What are the reasons for comment (2) and (3) in this context?

What are the specifications for custom deleter for std::unique_ptr?

2
Which part of this do you have trouble finding documentation for? - Kerrek SB

2 Answers

3
votes

For case 2) you are using a temporary, so the compiler can move it. On case 3) you are giving an object that cannot be moved, so the compiler will need to make a copy.

3
votes

The specification is accurately described on cppreference (constructors #3-4), and comes directly from the C++ standard section [unique.ptr.single.ctor]. Since your D is a non-reference type, the signatures are as follows:

unique_ptr(pointer p, const A& d);   // your (3)
unique_ptr(pointer p, A&& d);        // your (2)

where A is a synonym for D. These constructors require:

Requires:

— If D is not an lvalue-reference type then

  • If d is an lvalue or const rvalue then the first constructor of this pair will be selected. D shall satisfy the requirements of CopyConstructible (Table 21), and the copy constructor of Dshall not throw an exception. This unique_ptr will hold a copy of d.
  • Otherwise, d is a non-const rvalue and the second constructor of this pair will be selected. D shall satisfy the requirements of MoveConstructible (Table 20), and the move constructor of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.

The first bullet point describes your case (3), the second describes your case (2).