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

1309. Missing expressions for Move/CopyConstructible

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

Priority: Not Prioritized

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

View all issues with C++11 status.

Discussion:

Table 33 — MoveConstructible requirements [moveconstructible] and Table 34 — CopyConstructible requirements [copyconstructible] support solely the following expression:

T t(rv)

where rv is defined to be as "non-const rvalue of type T" and t as a "modifiable lvalue of type T" in 16.4.4.2 [utility.arg.requirements]/1.

This causes two different defects:

  1. We cannot move/copy-initialize a const lvalue of type T as in:

    int get_i();
    
    const int i1(get_i());
    

    both in Table 33 and in Table 34.

  2. The single support for

    T t(rv)
    

    in case of CopyConstructible means that we cannot provide an lvalue as a source of a copy as in

    const int& get_lri();
    
    int i2(get_lri());
    

I believe this second defect is due to the fact that this single expression supported both initialization situations according to the old (implicit) lvalue reference -> rvalue reference conversion rules.

Finally [copyconstructible] refers to some name u which is not part of the expression, and both [copyconstructible] and [moveconstructible] should support construction expressions from temporaries - this would be a stylistic consequence in the light of the new DefaultConstructible requirements and compared with existing requirements (see e.g. Container requirements or the output/forward iterator requirements)..

[ 2010-02-09 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

[ 2010-02-10 Reopened. The proposed wording of 1283(i) has been merged here. ]

[ 2010-02-10 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

Proposed resolution:

  1. Change 16.4.4.2 [utility.arg.requirements]/1 as indicated: [This change suggestion is motivated to make type descriptions clearer: First, a, b, and c may also be non-const T. Second, u is described in a manner consistent with the container requirements tables.]

    1 The template definitions in the C++ standard library refer to various named requirements whose details are set out in tables 31-38. In these tables, T is an object or reference type to be supplied by a C++ program instantiating a template; a, b, and c are values of type (possibly const) T; s and t are modifiable lvalues of type T; u denotes an identifier; is a value of type (possibly const) T; and rv is an non-const rvalue of type T; and v is an lvalue of type (possibly const) T or an rvalue of type const T.

  2. In 16.4.4.2 [utility.arg.requirements] Table 33 ([moveconstructible]) change as indicated [Note: The symbol u is defined to be either a const or a non-const value and is the right one we need here]:

    Table 33 — MoveConstructible requirements [moveconstructible]
    Expression Post-condition
    T tu(rv); tu is equivalent to the value of rv before the construction
    T(rv) T(rv) is equivalent to the value of rv before the construction
    [Note: There is no requirement on the value of rv after the construction. rv remains a valid object. Its state is unspecified.end note]
  3. In 16.4.4.2 [utility.arg.requirements] Table 34 ([copyconstructible]) change as indicated [Note: The symbol u is defined to be either a const or a non-const value and is the right one we need here. The expressions using a are recommended to ensure that lvalues are supported as sources of the copy expression]:

    Table 34 — CopyConstructible requirements [copyconstructible]
    (in addition to MoveConstructible)
    Expression Post-condition
    T tu(rv); the value of uv is unchanged and is equivalent to tu
    T(v) the value of v is unchanged and is equivalent to T(v)
    [Note: A type that satisfies the CopyConstructible requirements also satisfies the MoveConstructible requirements. — end note]
  4. In Table 35 — MoveAssignable requirements [moveassignable] change as indicated:

    Table 35 — MoveAssignable requirements [moveassignable]
    Expression Return type Return value Post-condition
    t = rv T& t t is equivalent to the value of rv before the assigment.
    [Note: There is no requirement on the value of rv after the assignment. rv remains a valid object. Its state is unspecified.end note]
  5. In 16.4.4.2 [utility.arg.requirements] change Table 36 as indicated:

    Table 36 — CopyAssignable requirements [copyassignable]
    (in addition to MoveAssignable)
    Expression Return type Return value Post-condition
    t = uv T& t t is equivalent to uv, the value of uv is unchanged
    [Note: A type that satisfies the CopyAssignable requirements also satisfies the MoveAssignable requirements. — end note]