std:: indirectly_writable
|
Определено в заголовочном файле
<iterator>
|
||
|
template
<
class
Out,
class
T
>
concept indirectly_writable
=
|
(начиная с C++20) | |
Концепт
indirectly_writable
<
Out, T
>
определяет требования для записи значения, чей тип и категория значения закодированы типом
T
в объект, на который ссылается итератор
Out
.
Семантические требования
Пусть
e
будет выражением, для которого
decltype
(
(
e
)
)
является
T
, и
o
будет разыменовываемым объектом типа
Out
, тогда
indirectly_writable
<
Out, T
>
моделируется только если:
-
Если
std::
indirectly_readable
<
Out
>
удовлетворяет требованиям и
std::
iter_value_t
<
Out
>
является тем же типом, что и
std::
decay_t
<
T
>
, тогда
*
o
после любого вышеуказанного присваивания равно значению
eдо присваивания.
o
не обязан быть разыменовываемым после вычисления любого из вышеуказанных выражений присваивания. Если
e
является xvalue, результирующее состояние объекта, который он обозначает, является допустимым, но неопределённым.
Сохранение равенства
Выражения, объявленные в requires выражениях концепций стандартной библиотеки, должны быть equality-preserving (если не указано иное).
Примечания
Единственное допустимое использование operator * — в левой части выражения присваивания. Присваивание через одно и то же значение косвенно записываемого типа может произойти только один раз.
Требуемые выражения с
const_cast
предотвращают
indirectly_readable
объекты с prvalue
reference
типами от случайного удовлетворения синтаксическим требованиям
indirectly_writable
, при этом позволяя прокси-ссылкам продолжать работать до тех пор, пока их константность является поверхностной. Смотрите
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, присваивает значение, на которое ссылается *i1 *i2 = o; // OK, но бессмысленно: присваивает временному объекту, возвращенному *i2 *i3 = o; // OK, вызывает ProxyReference::operator=(const Object& o) const // который выполняет *ptr = o, где ptr - это (*i3).p }