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 ) ;
} ;

/* 上記4つの式のいずれも等価性を保持する必要はない */
(C++20以降)

コンセプト indirectly_writable < Out, T > は、型と値カテゴリが T によってエンコードされた値を、イテレータ Out の参照先オブジェクトに書き込むための要件を規定します。

セマンティック要件

e decltype((e)) T となる式とし、 o を型 Out のデリファレンス可能なオブジェクトとするとき、 indirectly_writable < Out, T > がモデル化されるのは以下の場合のみです:

o は、上記の代入式の評価後にはデリファレンス可能である必要はありません。 e がxvalueの場合、それが示すオブジェクトの結果の状態は有効ですが未指定です。

等価性保存

標準ライブラリコンセプトの requires expressions で宣言される式は、 equality-preserving であることが要求されます(特に明記されている場合を除く)。

注記

operator * の唯一の有効な使用方法は、代入式の左辺でのみです。間接書き込み可能な型の同じ値を通じた代入は、一度だけ発生する可能性があります。

const_cast を用いた必要な式は、prvalueの reference 型を持つ indirectly_readable オブジェクトが誤って indirectly_writable の構文要件を満たすことを防ぎつつ、プロキシ参照がそのconst性が浅い限り動作し続けることを許可します。 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
}