Difference between revisions of "cpp/named req/MoveInsertable"
(~) |
(Added LWG issue #2177 DR (part 2/2).) |
||
(One intermediate revision by one user not shown) | |||
Line 1: | Line 1: | ||
− | {{cpp/named req/title|MoveInsertable|notes={{mark since c++11}} }} | + | {{cpp/named req/title|MoveInsertable|notes={{mark since c++11}}}} |
{{cpp/named req/navbar}} | {{cpp/named req/navbar}} | ||
Line 5: | Line 5: | ||
===Requirements=== | ===Requirements=== | ||
− | + | Given the following types, values and expressions: | |
− | + | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc | {{ | + | {{dsc hitem|Type|Definition}} |
− | {{dsc | {{ | + | {{dsc|{{tt|T}}|an object type}} |
− | {{dsc | {{ | + | {{dsc|{{tt|A}}|an allocator type}} |
− | {{dsc | {{ | + | {{dsc|{{tt|X}}|a container type satisfying all following conditions: |
+ | * {{tt|X::value_type}} is the same as {{tt|T}}. | ||
+ | * {{tt|X::allocator_type}} is the same as {{c/core|std::allocator_traits<A>::rebind_alloc<T>}}. | ||
+ | }} | ||
+ | {{dsc hitem|Value|Definition}} | ||
+ | {{dsc|{{c|m}}|an lvalue of type {{tt|A}}}} | ||
+ | {{dsc|{{c|p}}|a pointer of type {{tt|T*}}}} | ||
+ | {{dsc hitem|Expression|Definition}} | ||
+ | {{dsc|{{c|rv}}|an expression denoting an rvalue of type {{tt|T}}}} | ||
+ | {{dsc|{{c|expr}}|{{c|std::allocator_traits<A>::construct(m, p, rv)}}}} | ||
{{dsc end}} | {{dsc end}} | ||
− | + | {{tt|T}} is {{named req/core|MoveInsertable}} into {{tt|X}} if all following conditions are satisfied: | |
− | + | * {{c|expr}} is well-formed. | |
− | + | * Right after the evaluation of {{c|expr}}, the value of {{c|*p}} is equivalent to the value of {{c|rv}} before the evaluation. | |
− | + | ||
− | {{ | + | |
− | + | ||
− | }} | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
===Notes=== | ===Notes=== | ||
− | If {{tt|A}} is {{c|std::allocator<T>}}, then this will call placement | + | If {{tt|A}} is {{c/core|std::allocator<T>}}, then this will call placement {{c/core|new}}, as by {{rev inl|until=c++20|{{c|::new((void*)p) T(rv)}}}}{{rev inl|since=c++20|{{c|std::construct_at(p, rv)}}}}. This effectively requires {{tt|T}} to be move constructible. |
− | If {{c|std::allocator<T>}} or a similar allocator is used, a class does not have to implement a | + | If {{c/core|std::allocator<T>}} or a similar allocator is used, a class does not have to implement a {{lt|cpp/language/move constructor}} to satisfy this type requirement: a {{lt|cpp/language/copy constructor}} that takes a {{c/core|const T&}} argument can bind rvalue expressions. If a {{named req/core|MoveInsertable}} class implements a move constructor, it may also implement [[cpp/utility/move|move semantics]] to take advantage of the fact that the value of {{tt|rv}} after construction is unspecified. |
Although it is required that customized {{tt|construct}} is used when constructing elements of {{lc|std::basic_string}} until C++23, all implementations only used the default mechanism. The requirement is corrected by {{wg21|P1072R10}} to match existing practice. | Although it is required that customized {{tt|construct}} is used when constructing elements of {{lc|std::basic_string}} until C++23, all implementations only used the default mechanism. The requirement is corrected by {{wg21|P1072R10}} to match existing practice. | ||
+ | |||
+ | ===Defect reports=== | ||
+ | {{dr list begin}} | ||
+ | {{dr list item|wg=lwg|dr=2177|std=C++11|before=evaluting {{c|expr}} did not have any postcondition|after=added}} | ||
+ | {{dr list end}} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc | {{named req|CopyInsertable}} }} | + | {{dsc|{{named req|CopyInsertable}}}} |
{{dsc end}} | {{dsc end}} | ||
{{langlinks|de|es|ja|ru|zh}} | {{langlinks|de|es|ja|ru|zh}} |
Latest revision as of 23:04, 21 October 2024
Specifies that an object of the type can be constructed into uninitialized storage from an rvalue of that type by a given allocator.
Contents |
[edit] Requirements
Given the following types, values and expressions:
Type | Definition |
T
|
an object type |
A
|
an allocator type |
X
|
a container type satisfying all following conditions:
|
Value | Definition |
m | an lvalue of type A
|
p | a pointer of type T*
|
Expression | Definition |
rv | an expression denoting an rvalue of type T
|
expr | std::allocator_traits<A>::construct(m, p, rv) |
T
is MoveInsertable into X
if all following conditions are satisfied:
- expr is well-formed.
- Right after the evaluation of expr, the value of *p is equivalent to the value of rv before the evaluation.
[edit] Notes
If A
is std::allocator<T>, then this will call placement new, as by ::new((void*)p) T(rv)(until C++20)std::construct_at(p, rv)(since C++20). This effectively requires T
to be move constructible.
If std::allocator<T> or a similar allocator is used, a class does not have to implement a move constructor to satisfy this type requirement: a copy constructor that takes a const T& argument can bind rvalue expressions. If a MoveInsertable class implements a move constructor, it may also implement move semantics to take advantage of the fact that the value of rv
after construction is unspecified.
Although it is required that customized construct
is used when constructing elements of std::basic_string until C++23, all implementations only used the default mechanism. The requirement is corrected by P1072R10 to match existing practice.
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 2177 | C++11 | evaluting expr did not have any postcondition | added |
[edit] See also
CopyInsertable |