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 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]