This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 1322. Explicit `CopyConstructible` requirements are insufficient

Section: 16.4.4.2 [utility.arg.requirements] Status: Resolved Submitter: Daniel Krügler Opened: 2010-02-16 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [utility.arg.requirements].

View all issues with Resolved status.

Discussion:

With the acceptance of library defect 822 only direct-initialization is supported, and not copy-initialization in the requirement sets `MoveConstructible` and `CopyConstructible`. This is usually a good thing, if only the library implementation needs to obey these restrictions, but the Empire strikes back quickly:

1. Affects user-code: `std::exception_ptr` is defined purely via requirements, among them `CopyConstructible`. A strict reading of the standard would make implementations conforming where `std::exception_ptr` has an explicit copy-c'tor and user-code must code defensively. This is a very unwanted effect for such an important component like `std::exception_ptr`.

2. Wrong re-use: Recently proposed requirement sets (`NullablePointer` as of N3025, Hash) or cleanup of existing requirement sets (e.g. iterator requirements as of N3046) tend to reuse existing requirement sets, so reusing `CopyConstructible` is attempting, even in cases, where the intend is to support copy-initialization as well.

3. Inconsistency: The current iterator requirements set Table 102 (output iterator requirements) and Table 103 (forward iterator requirements) demonstrate quite clearly a strong divergence of copy-semantics: The specified semantics of

   >     X u(a);
   >     X u = a;

   are underspecified compared to the most recent clarifications of the `CopyConstructible` requirements, c.f. issue 1309 which is very unsatisfactory. This will become worse for each further issue that involves the `CopyConstructible` specification (for possible directions see 1173).

The suggested resolution is to define two further requirements `implicit-MoveConstructible` and `implicit-CopyConstructible` (or any other reasonable name like `MoveConvertible` and `CopyConvertible`) each with a very succinct but precise meaning solving all three problems mentioned above.

[Batavia: Resolved by accepting n3215.]

Proposed resolution:

1. Add the following new table ?? after Table 34 — `MoveConstructible` requirements [moveconstructible]:

   > Table ?? — `Implicit MoveConstructible` requirements [implicit.moveconstructible] (in addition to `MoveConstructible`)
   > Expression | Operational Semantics
   > --- | ---
   > `T u = rv;` | Equivalent to: `T u(rv);`

2. Add the following new table ?? after Table 35 — `CopyConstructible` requirements [copyconstructible]:

   > Table ?? — `Implicit CopyConstructible` requirements [implicit.copyconstructible] (in addition to `CopyConstructible`)
   > Expression | Operational Semantics
   > --- | ---
   > `T u = v;` | Equivalent to: `T u(v);`

3. Change 16.4.4.4 [nullablepointer.requirements]/1 as follows:

   > A `NullablePointer` type is a pointer-like type that supports null values. A type `P` meets the requirements of `NullablePointer` if:

   > - `P` satisfies the requirements of `EqualityComparable`, `DefaultConstructible`, `implicit CopyConstructible`, `CopyAssignable`, and `Destructible`,
   > - [..]

4. Change 16.4.4.5 [hash.requirements]/1 as indicated: [explicit copy-constructible functors could not be provided as arguments to any algorithm that takes these by value. Also a typo is fixed.]

   > 1 A type `H` meets the Hash requirements if:

   > - it is a function object type (20.8),
   > - it satisfies ifes the requirements of `implicit CopyConstructible` and `Destructible` (20.2.1),
   > - [..]

5. Change 21.3.2 [meta.rqmts]/1+2 as indicated:

   > 1 A UnaryTypeTrait describes a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described. It shall be `DefaultConstructible`, `implicit CopyConstructible`, [..]

   > 2 A `BinaryTypeTrait` describes a relationship between two types. It shall be a class template that takes two template type arguments and, optionally, additional arguments that help define the relationship being described. It shall be `DefaultConstructible`, `implicit CopyConstructible`, and [..]

6. Change 22.10.4 [func.require]/4 as indicated: [explicit copy-constructible functors could not be provided as arguments to any algorithm that takes these by value]

   > 4 Every call wrapper (20.8.1) shall be `implicit MoveConstructible`. A simple call wrapper is a call wrapper that is `implicit CopyConstructible` and `CopyAssignable` and whose copy constructor, move constructor, and assignment operator do not throw exceptions. [..]

7. Change 22.10.6 [refwrap]/1 as indicated:

   > 1 `reference_wrapper<T>` is an `implicit` `CopyConstructible` and `CopyAssignable` wrapper around a reference to an object or function of type `T`.

8. Change 22.10.15.4 [func.bind.bind]/5+9 as indicated:

   > 5 Remarks: The return type shall satisfy the requirements of `implicit MoveConstructible`. If all of `FD` and `TiD` satisfy the requirements of `CopyConstructible`, then the return type shall satisfy the requirements of `implicit CopyConstructible`. [Note: this implies that all of `FD` and `TiD` are `MoveConstructible`. — end note]

   > [..]

   > 9 Remarks: The return type shall satisfy the requirements of `implicit MoveConstructible`. If all of `FD` and `TiD` satisfy the requirements of `CopyConstructible`, then the return type shall satisfy the requirements of `implicit CopyConstructible`. [Note: this implies that all of `FD` and `TiD` are `MoveConstructible`. — end note]

9. Change 22.10.15.5 [func.bind.place] as indicated:

   > 1 All placeholder types shall be `DefaultConstructible` and `implicit CopyConstructible`, and [..]

10. Change 20.3.1 [unique.ptr]/5 as indicated:

    > 5 Each object of a type `U` instantiated form the `unique_ptr` template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such `U` is `implicit MoveConstructible` and `MoveAssignable`, but is not `CopyConstructible` nor `CopyAssignable`. The template parameter `T` of `unique_ptr` may be an incomplete type.

11. Change 20.3.2.2 [util.smartptr.shared]/2 as indicated:

    > 2 Specializations of `shared_ptr` shall be `implicit CopyConstructible`, `CopyAssignable`, and `LessThanComparable`, [..]

12. Change 20.3.2.3 [util.smartptr.weak]/2 as indicated:

    > 2 Specializations of `weak_ptr` shall be `implicit CopyConstructible` and `CopyAssignable`, allowing their use in standard containers. The template parameter `T` of `weak_ptr` may be an incomplete type.

13. Change 25.3.5.2 [iterator.iterators]/2 as indicated: [This fixes a defect in the Iterator requirements. None of the usual algorithms accepting iterators would be usable with iterators with explicit copy-constructors]

    > 2 A type `X` satisfies the Iterator requirements if:

    > - `X` satisfies the `implicit CopyConstructible`, `CopyAssignable`, and `Destructible` requirements (20.2.1) and lvalues of type `X` are swappable (20.2.2), and [..]
    > - ...

14. Change 99 [auto.ptr]/3 as indicated:

    > 3 [..] Instances of `auto_ptr` meet the requirements of `implicit MoveConstructible` and `MoveAssignable`, but do not meet the requirements of `CopyConstructible` and `CopyAssignable`. — end note]