std::indirectly_writable
Defined in header <iterator> | ||
template<class Out, class T > concept indirectly_writable = | (since C++20) | |
The concept indirectly_writable<Out, T> specifies the requirements for writing a value whose type and value category are encoded by T
into an iterator Out
's referenced object.
[edit]Semantic requirements
Let e
be an expression such that decltype((e)) is T
, and o
be a dereferenceable object of type Out
, then indirectly_writable<Out, T> is modeled only if:
- If std::indirectly_readable<Out> is modeled and std::iter_value_t<Out> is the same type as std::decay_t<T>, then *o after any above assignment is equal to the value of
e
before the assignment.
o
is not required to be dereferenceable after evaluating any of the assignment expressions above. If e
is an xvalue, the resulting state of the object it denotes is valid but unspecified.
[edit]Equality preservation
Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).
[edit]Notes
The only valid use of operator* is on the left side of an assignment expression. Assignment through the same value of an indirectly writable type may happen only once.
The required expressions with const_cast
prevent indirectly_readable
objects with prvalue reference
types from satisfying the syntactic requirements of indirectly_writable
by accident, while permitting proxy references to continue to work as long as their constness is shallow. See Ranges TS issue 381.
struct Object { Object& operator=(const Object& other)=default; int x;}; struct ProxyReference { ProxyReference& operator=(const ProxyReference& other)=default; const ProxyReference& operator=(const Object& o)const{*p = o;return*this;} Object* p;}; struct I1 { Object& operator*();}; struct I2 { Object operator*();}; struct I3 { ProxyReference operator*();}; static_assert(std::indirectly_writable<I1, Object>); static_assert(!std::indirectly_writable<I2, Object>); static_assert(std::indirectly_writable<I3, Object>); static_assert(!std::indirectly_writable<I3, ProxyReference>); void f(I1 i1, I2 i2, I3 i3, Object o){*i1 = o;// OK, assigns to the value referenced by *i1 *i2 = o;// OK, but meaningless: This assigns to the temporary returned by *i2 *i3 = o;// OK, calls ProxyReference::operator=(const Object& o) const// which performs *ptr = o, where ptr is (*i3).p}