Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/named req/MoveInsertable"

From cppreference.com
< cpp‎ | named req
(~)
(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:
The type {{ttb|T}} is {{named req|MoveInsertable}} into the container {{ttb|X}} whose {{tt|value_type}} is identical to {{tt|T}} if, given
+
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc | {{ttb|A}} | an allocator type}}
+
{{dsc hitem|Type|Definition}}
{{dsc | {{ttb|m}} | an lvalue of type {{ttb|A}} }}
+
{{dsc|{{tt|T}}|an object type}}
{{dsc | {{ttb|p}} | the pointer of type {{ttb|T*}} prepared by the container }}
+
{{dsc|{{tt|A}}|an allocator type}}
{{dsc | {{ttb|rv}} | rvalue expression of type {{ttb|T}}}}
+
{{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}}
  
where {{ttb|X::allocator_type}} is identical to {{c|std::allocator_traits<A>::rebind_alloc<T>}},
+
{{tt|T}} is {{named req/core|MoveInsertable}} into {{tt|X}} if all following conditions are satisfied:
 
+
* {{c|expr}} is well-formed.
the following expression 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.
 
+
{{source|
+
std::allocator_traits<A>::construct(m, p, rv);
+
}}
+
 
+
And after evaluation, the value of {{tt|*p}} is equivalent to the value formerly held by {{tt|rv}} ({{tt|rv}} remains valid, but is in an unspecified state.)
+
 
+
If {{ttb|X}} is not allocator-aware or is a {{lc|std::basic_string}} specialization, the term is defined as if {{ttb|A}} were {{lc|std::allocator<T>}}, except that no allocator object needs to be created, and user-defined specializations of {{lc|std::allocator}} are not instantiated.
+
  
 
===Notes===
 
===Notes===
If {{tt|A}} is {{c|std::allocator<T>}}, then this will call placement-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 {{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 [[cpp/language/move constructor|move constructor]] to satisfy this type requirement: a [[cpp/language/copy constructor|copy constructor]] that takes a {{c|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.
+
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

 
 
C++ named requirements
 

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:
  • X::value_type is the same as T.
  • X::allocator_type is the same as std::allocator_traits<A>::rebind_alloc<T>.
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