Title
Explicit CopyConstructible requirements are insufficient
Status
resolved
Section
[utility.arg.requirements]
Submitter
Daniel Krügler

Created on 2010-02-16.00:00:00 last changed 170 months ago

Messages

Date: 2010-11-09.01:35:58

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 [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 [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 satisfiesifes the requirements of implicit CopyConstructible and Destructible (20.2.1),
    • [..]
  5. Change [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 [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 [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 [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 [func.bind.place] as indicated:

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

  10. Change [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 [util.smartptr.shared]/2 as indicated:

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

  12. Change [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 [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 [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]

Date: 2010-11-13.01:40:56

[ Batavia: Resolved by accepting n3215. ]

Date: 2010-02-16.00:00:00

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.

History
Date User Action Args
2010-11-18 12:46:23adminsetstatus: nad editorial -> resolved
2010-11-13 01:40:56adminsetstatus: open -> nad editorial
2010-11-09 14:17:26adminsetstatus: nad -> open
2010-11-09 01:35:58adminsetmessages: + msg5321
2010-11-09 01:35:58adminsetstatus: new -> nad
2010-10-21 18:28:33adminsetmessages: + msg1596
2010-02-16 00:00:00admincreate