Namespaces
Variants

std:: indirectly_writable

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
定义于头文件 <iterator>
template < class Out, class T >

concept indirectly_writable =
requires ( Out && o, T && t ) {
* o = std:: forward < T > ( t ) ;
* std:: forward < Out > ( o ) = std:: forward < T > ( t ) ;
const_cast < const std:: iter_reference_t < Out > && > ( * o ) = std:: forward < T > ( t ) ;
const_cast < const std:: iter_reference_t < Out > && > ( * std:: forward < Out > ( o ) ) =
std:: forward < T > ( t ) ;
} ;

/* 以上四个表达式均不要求保持相等性 */
(C++20 起)

概念 indirectly_writable < Out, T > 规定了将类型和值类别由 T 编码的值写入迭代器 Out 所引用对象的要求。

语义要求

e 为表达式,使得 decltype ( ( e ) ) T ,且 o 为类型 Out 的可解引用对象,则仅当满足以下条件时, indirectly_writable < Out, T > 概念被建模:

o 在上述任意赋值表达式求值后不要求保持可解引用状态。若 e 为右值,则其所指代对象的结果状态有效但未指定。

等值保持性

标准库概念的 requires 表达式 中声明的表达式必须满足 等值保持 要求(除非另有说明)。

注释

唯一有效的 operator * 使用方式是在赋值表达式的左侧。通过同一可间接写入类型值的赋值操作最多只能发生一次。

使用 const_cast 的必要表达式可防止具有纯右值 reference 类型的 indirectly_readable 对象意外满足 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;  // 正确:赋值给 *i1 所引用的值
    *i2 = o;  // 正确但无意义:这是赋值给 *i2 返回的临时对象
    *i3 = o;  // 正确:调用 ProxyReference::operator=(const Object& o) const
              // 执行 *ptr = o,其中 ptr 是 (*i3).p
}