@@ -29,7 +29,30 @@ namespace std {
29
29
30
30
このコンセプトを構成する4つの制約式は全て、[等しさを保持](/reference/concepts.md)することを要求しない。
31
31
32
- `const_cast`を用いる制約式は、右辺値に対しても代入できるが`const`な右辺値では代入できなくなる非プロキシイテレータの*prvalue*(例えば`std::string`そのものなど)を返すイテレータを弾くためにある。これによって、間接参照が*prvalue*を返すようなイテレータ型は`indirectly_writable`のモデルとならないが、出力可能なプロキシオブジェクトを返すイテレータは`indirectly_writable`のモデルとなる事ができる。
32
+ ### 制約式について
33
+
34
+ `const_cast`を用いる制約式は、非プロキシオブジェクト(値を所有するオブジェクトのことである。[`std::string`](/reference/string/basic_string.md)などが該当)を弾くために存在する。
35
+
36
+ まず前提として、非プロキシオブジェクトは[メンバ関数の左辺値/右辺値修飾](https://cpprefjp.github.io/lang/cpp11/ref_qualifier_for_this.html)が追加される以前からの慣習により、*pvalue*であっても代入が可能である。また、値を所有するために`const`が付与されれば代入は不可能となる。
37
+
38
+ ```cpp example
39
+ #include <string>
40
+
41
+ int main()
42
+ {
43
+ std::string() = "string"; // pvalueに代入
44
+ }
45
+ ```
46
+
47
+ このような非プロキシオブジェクトの* pvalue* がイテレータの間接参照結果として返された場合、それに書き込んだとしても、その* pvalue* のオブジェクトが所有する値を書き換えるのみであり、正しく出力されるとは言えない。
48
+
49
+ 一方で、プロキシオブジェクト(所有権を持たず、他のオブジェクトを参照するオブジェクト)がイテレータの間接参照結果として返された場合は、* pvalue* の場合も代入された値を「参照する先のオブジェクトが所有する値」へ書き込むことによって、正しく出力を完了することが出来る。
50
+
51
+ 更に、プロキシオブジェクトは値を所有しないため「` const ` な参照先」でなければ、プロキシオブジェクトそれ自体が` const ` であっても代入は可能であるべきである。しかしながら、従来のプロキシオブジェクトは` const ` を付与された場合代入が不可能になる実装が殆どであり、変更が必要である。例としては[ ` std::vector<bool>::reference ` ] ( /reference/vector/vector.md ) がある。
52
+
53
+ プロキシオブジェクトの他にも、参照(右辺値参照/左辺値参照問わず)も正しく出力が可能である。このことから、「` const ` を付与した上でも代入が可能であるようなプロキシオブジェクト」と「参照」を合わせて「プロキシ参照(proxy reference)」と呼称することがある。
54
+
55
+ 以上のことから、` const ` を付与した際にも代入が可能であればプロキシ参照、不可能であれば非プロキシ参照と区別することが可能となる。したがって、間接参照が非プロキシ参照(プロキシオブジェクトでない* pvalue* など)を返すイテレータ型は本コンセプトのモデルとならず、プロキシ参照を返すイテレータは本コンセプトのモデルとなる事ができる。
33
56
34
57
## モデル
35
58
@@ -51,6 +74,8 @@ indirectly_readable<Out> && same_as<iter_value_t<Out>, decay_t<T>>
51
74
` indirectly_writable ` のモデルとなる` Out ` の` operator* ` は出力(上記式による代入文の左辺に来ること)だけが唯一有効な使用法であり、[ ` indirectly_readable ` ] ( indirectly_readable.md ) である必要はない。
52
75
53
76
## 例
77
+
78
+ ### C++20
54
79
``` cpp example
55
80
#include < iostream>
56
81
#include < concepts>
@@ -96,7 +121,7 @@ int main() {
96
121
```
97
122
* std::indirectly_writable[color ff0000]
98
123
99
- ### 出力
124
+ #### 出力
100
125
```
101
126
int* is indirectly writable int
102
127
std::unique_ptr<int > is indirectly writable int&
@@ -109,6 +134,60 @@ std::optional<int> is not indirectly writable int
109
134
not_writable is not indirectly writable int
110
135
```
111
136
137
+
138
+ ### C++23 で満たすようになった型
139
+ ```cpp example
140
+ #include <iostream>
141
+ #include <concepts>
142
+ #include <iterator>
143
+ #include <utility>
144
+ #include <tuple>
145
+ #include <vector>
146
+
147
+ template <typename Out, typename T>
148
+ requires std::indirectly_writable<Out, T>
149
+ void f(const char* out, const char* t)
150
+ {
151
+ std::cout << out << " is indirectly writable " << t << std::endl;
152
+ }
153
+
154
+ template <typename Out, typename T>
155
+ void f(const char* out, const char* t)
156
+ {
157
+ std::cout << out << " is not indirectly writable " << t << std::endl;
158
+ }
159
+
160
+ struct ret_proxy_pair
161
+ {
162
+ // 全ての要素がプロキシ参照である pair はプロキシ参照
163
+ std::pair<int&, std::pair<int&, int&>> operator*();
164
+ };
165
+
166
+ struct ret_proxy_tuple
167
+ {
168
+ // 全ての要素がプロキシ参照である tuple はプロキシ参照
169
+ std::tuple<int&, std::tuple<int&>> operator*();
170
+ };
171
+
172
+
173
+ int main()
174
+ {
175
+ f<std::vector<bool>::iterator, bool>("std::vector<bool>::iterator", "bool");
176
+ f<ret_proxy_pair, std::pair<int, std::pair<int, int>>>("ret_proxy_pair", "std::pair<int, std::pair<int, int>>");
177
+ f<ret_proxy_tuple, std::tuple<int, std::tuple<int>>>("ret_proxy_tuple", "std::tuple<int, std::tuple<int>>");
178
+ }
179
+ ```
180
+ * std::indirectly_writable[ color ff0000]
181
+
182
+ #### 出力
183
+ ```
184
+ std::vector<bool>::iterator is indirectly writable bool
185
+ ret_proxy_pair is indirectly writable std::pair<int, std::pair<int, int>>
186
+ ret_proxy_tuple is indirectly writable std::tuple<int, std::tuple<int>>
187
+
188
+ ```
189
+
190
+
112
191
## バージョン
113
192
### 言語
114
193
- C++20
0 commit comments