Skip to content

Commit b2f6285

Browse files
committed
P2165R4(#1083), P2255R2(#1070), P2321R2(#1063)
- P2165R4, P2255R2: 全対応 - P2321R2: `pair`/`tuple`/`vector<bool>::reference`について対応 - 一部説明専用コンセプトを独立ページへ - `not-same-as`を`different-from`へ変更
1 parent bc23c73 commit b2f6285

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1816
-287
lines changed

lang/cpp20/converting_from_pointer_to_bool_should_be_considered_narrowing.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ std::variant<bool, int> v = b[1]; // intを保持して構築されてしまう
4040
* bitset[link /reference/bitset/bitset.md]
4141
* variant[link /reference/variant/variant.md]
4242
43-
`std::bitset`の非`const`な[`operator[]`](/reference/bitset/bitset/op_at.md)は`bool`型へ暗黙変換可能なプロクシオブジェクトを返す
43+
`std::bitset`の非`const`な[`operator[]`](/reference/bitset/bitset/op_at.md)は`bool`型へ暗黙変換可能なプロキシオブジェクトを返す
4444
4545
`std::variant`の構築・代入時に縮小変換が起こることを検出して防止することはライブラリレベルで可能だったが、ポインタ型から`bool`への変換を縮小変換として扱うということはライブラリレベルでは実装できなかったため`bool`への変換全体を禁止せざるを得ず、このような問題が発生していた。
4646

lang/cpp23.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ C++23とは、2023年中に改訂される予定の、C++バージョンの通
216216
- [`<type_traits>`](/reference/type_traits.md)に、スコープ付き列挙型かを判定する型特性[`std::is_scoped_enum`](/reference/type_traits/is_scoped_enum.md)を追加
217217
- [`<type_traits>`](/reference/type_traits.md)に、第1テンプレート引数についている型修飾を外す型特性として、以下を追加:
218218
- [`<type_traits>`](/reference/type_traits.md)に、一時オブジェクトの参照への束縛を検出するための型特性として、以下を追加:
219-
- [`std::reference_constructs_from_temporary`](/reference/type_traits/reference_constructs_from_temporary.md.nolink)
220-
- [`std::reference_converts_from_temporary`](/reference/type_traits/reference_converts_from_temporary.md.nolink)
219+
- [`std::reference_constructs_from_temporary`](/reference/type_traits/reference_constructs_from_temporary.md)
220+
- [`std::reference_converts_from_temporary`](/reference/type_traits/reference_converts_from_temporary.md)
221221

222222

223223
### C互換ライブラリ

reference/concepts/Invoke.md

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ C++における関数呼び出しという性質を抽象化しまとめた、
6060
- それ以外の場合は、*INVOKE*`(f, t1, t2, ..., tN)` の実行結果の戻り値が型 `R` に暗黙的に変換されること。
6161
3. すべての *call-wrapper* は、*Cpp17MoveConstructible* かつ *Cpp17Destructible* でなければならない。
6262

63+
## 要件(C++23差分)
64+
C++20 における 2. について、次の文言を項目の最後に追加する。この変更は、`R`が参照かつ*INVOKE*の実行結果が`R`に束縛されることで寿命が延長される場合にダングリング参照が作成されてしまう事例を検出するための要件である。
65+
66+
- [`reference_­converts_­from_­temporary_­v`](/reference/type_traits/reference_converts_from_temporary.md)`<R, decltype(`*INVOKE*`(f, t1, t2, …, tN))> == true`の場合、*INVOKE*`<R>(f, t1, t2, …, tN)`は不適格。
67+
6368

6469
## まとめ
6570
[第1引数がメンバ関数へのポインタの場合でも非静的メンバデータへのポインタの場合でも,第2引数がクラスオブジェクトへの参照の場合でもポインタの場合でもポインタっぽいものの場合でも,なんか知らんけどそれっぽく上手くいく](https://twitter.com/Cryolite/status/216814363221303296) ように取り計らった操作のことである。

reference/exposition-only.md

+36-19
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,52 @@
11
# 説明専用ライブラリ
2+
23
* exposition-only[meta header]
34

45
このページでは、説明専用のライブラリをまとめる。
56
これらはC++規格の文章中に現れる説明のためのものであり、実際に使うことはできない。
67

7-
| 名前 | 説明 | 対応バージョン |
8-
|-----------------------------------------------------------------------|-------------------------|----------------|
9-
| [`decay-copy`](exposition-only/decay-copy.md) | [`decay`](/reference/type_traits/decay.md)した型にコピーまたはムーブする (function template) | C++20 |
10-
| [`synth-three-way`](exposition-only/synth-three-way-result.md) | 三方比較可能であればそれを行い、そうでなければ三方比較を実装して比較を行う (variable) | C++20 |
11-
| [`synth-three-way-result`](exposition-only/synth-three-way-result.md) | `synth-three-way`関数オブジェクトでの比較結果の型 (function template) | C++20 |
8+
| 名前 | 説明 | 対応バージョン |
9+
|-----------------------------------------------------------------------|-------------------------------------------------------------------------------|-----------|
10+
| [`decay-copy`](exposition-only/decay-copy.md) | [`decay`](/reference/type_traits/decay.md)した型にコピーまたはムーブする (function template) | C++20 |
11+
| [`synth-three-way`](exposition-only/synth-three-way-result.md) | 三方比較可能であればそれを行い、そうでなければ三方比較を実装して比較を行う (variable) | C++20 |
12+
| [`synth-three-way-result`](exposition-only/synth-three-way-result.md) | `synth-three-way`関数オブジェクトでの比較結果の型 (function template) | C++20 |
1213

1314
## `<concepts>`
1415

15-
| 名前 | 説明 | 対応バージョン |
16-
|------|------|----------------|
17-
| [`boolean-testable`](concepts/boolean-testable.md) | 真理値型 (concept) | C++20 |
16+
| 名前 | 説明 | 対応バージョン |
17+
|----------------------------------------------------|------------------|-----------|
18+
| [`boolean-testable`](concepts/boolean-testable.md) | 真理値型 (concept) | C++20 |
1819

1920
## `<iterator>`
2021

21-
| 名前 | 説明 | 対応バージョン |
22-
|------------------------------|-------------------------------------------------|----------------|
23-
| [`with-reference`](iterator/dereferenceable.md) |`T`に参照を付加する (alias template) | C++20 |
24-
| [`can-reference`](iterator/dereferenceable.md) | `with-reference`可能 (concept) | C++20 |
25-
| [`dereferenceable`](iterator/dereferenceable.md) | 単純な間接参照が可能 (concept) | C++20 |
26-
| [`is-integer-like`](iterator/is_integer_like.md) | 符号付整数型と同等の型か否かを表す (variable template) | C++20 |
27-
| [`is-signed-integer-like`](iterator/is_integer_like.md) | 符号なし整数型と同等の型か否かを表す (variable template) | C++20 |
22+
| 名前 | 説明 | 対応バージョン |
23+
|---------------------------------------------------------|-------------------------------------------------------------|-----------|
24+
| [`with-reference`](iterator/dereferenceable.md) |`T`に参照を付加する (alias template) | C++20 |
25+
| [`can-reference`](iterator/dereferenceable.md) | [`with-reference`](iterator/dereferenceable.md)可能 (concept) | C++20 |
26+
| [`dereferenceable`](iterator/dereferenceable.md) | 単純な間接参照が可能 (concept) | C++20 |
27+
| [`is-integer-like`](iterator/is_integer_like.md) | 符号付整数型と同等の型か否かを表す (variable template) | C++20 |
28+
| [`is-signed-integer-like`](iterator/is_integer_like.md) | 符号なし整数型と同等の型か否かを表す (variable template) | C++20 |
2829

2930
## `<ranges>`
30-
| 名前 | 説明 | 対応バージョン |
31-
|--------------------------------------------|---------------------------------------------------------------------------------|----------------|
32-
| [`copyable-box`](ranges/copyable_box.md) | コピー可能、または例外なしでムーブ可能な場合のみ値を保持する型 (class template) | C++20 |
31+
32+
| 名前 | 説明 | 対応バージョン |
33+
|----------------------------------------------|------------------------------------------------------------------------------------------------------|-----------|
34+
| [`copyable-box`](ranges/copyable_box.md) | コピー可能、または例外なしでムーブ可能な場合のみ値を保持する型 (class template) | C++20 |
35+
| [`simple-view`](ranges/simple-view.md) | 単純なビューを表す (concept) | C++20 |
36+
| [`has-arrow`](ranges/has-arrow.md) | [`std::input_iterator`](/reference/iterator/input_iterator.md)を満たし、アロー演算子が使用できる型かを表す (concept) | C++20 |
37+
| [`different-from`](ranges/different-from.md) | `const`/`volatile`修飾を無視して、2つの型が同じでないことを表す (concept) | C++20 |
38+
| [`uses-nonqualification-pointer-conversion`](ranges/subrange/uses-nonqualification-pointer-conversion.md) | 直接変換できない型同士のポインタの変換が必要かどうかを表す (concept) | C++20 |
39+
| [`convertible-to-non-slicing`](ranges/subrange/convertible-to-non-slicing.md) | スライシングを起こさずに変換できるかどうかを表す (concept) | C++20 |
40+
| [`pair-like-convertible-from`](ranges/subrange/pair-like-convertible-from.md) | ある2つの型から構築出来る[`pair-like`](tuple/pair-like.md)な型を表す (concept) | C++20 |
41+
42+
## `<tuple>`
43+
44+
| 名前 | 説明 | 対応バージョン |
45+
|-------------------------------------|---------------------------------------------|-----------|
46+
| [`tuple-like`](tuple/tuple-like.md) | [`tuple`](tuple/tuple.md)のような型を表す (concept) | C++23 |
47+
| [`pair-like`](tuple/pair-like.md) | [`pair`](utility/pair.md)のような型を表す (concept) | C++20 |
3348

3449
## 参照
35-
- [N4861 16.4.2.1 Exposition-only functions](https://timsong-cpp.github.io/cppwp/n4861/expos.only.func)
50+
51+
* [N4861 16.4.2.1 Exposition-only functions](https://timsong-cpp.github.io/cppwp/n4861/expos.only.func)
52+
* [LWG 3404 Finish removing `subrange`'s conversions from `pair-like`](https://cplusplus.github.io/LWG/issue3404)

reference/iterator/indirectly_writable.md

+81-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,30 @@ namespace std {
2929
3030
このコンセプトを構成する4つの制約式は全て、[等しさを保持](/reference/concepts.md)することを要求しない。
3131
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*など)を返すイテレータ型は本コンセプトのモデルとならず、プロキシ参照を返すイテレータは本コンセプトのモデルとなる事ができる。
3356

3457
## モデル
3558

@@ -51,6 +74,8 @@ indirectly_readable<Out> && same_as<iter_value_t<Out>, decay_t<T>>
5174
`indirectly_writable`のモデルとなる`Out``operator*`は出力(上記式による代入文の左辺に来ること)だけが唯一有効な使用法であり、[`indirectly_readable`](indirectly_readable.md)である必要はない。
5275

5376
##
77+
78+
### C++20
5479
```cpp example
5580
#include <iostream>
5681
#include <concepts>
@@ -96,7 +121,7 @@ int main() {
96121
```
97122
* std::indirectly_writable[color ff0000]
98123
99-
### 出力
124+
#### 出力
100125
```
101126
int* is indirectly writable int
102127
std::unique_ptr<int> is indirectly writable int&
@@ -109,6 +134,60 @@ std::optional<int> is not indirectly writable int
109134
not_writable is not indirectly writable int
110135
```
111136
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+
112191
## バージョン
113192
### 言語
114193
- C++20

reference/ranges/different-from.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# different-from
2+
* ranges[meta header]
3+
* concept[meta id-type]
4+
* cpp20[meta cpp]
5+
6+
```cpp
7+
template<class T, class U>
8+
concept different-from = // 説明専用コンセプト
9+
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
10+
```
11+
* same_as[link /reference/concepts/same_as.md]
12+
* remove_cvref_t[link /reference/type_traits/remove_cvref.md]
13+
14+
## 概要
15+
`different-from`は、型`T`、`U`について`const`/`volatile`修飾を無視して、同じ型でないことを表す説明専用コンセプトである。
16+
17+
18+
## 備考
19+
N4885 までは`not-same-as`という名称だったが、実際には[`same_as`](/reference/concepts/same_as.md)の否定とは等価ではない(本説明専用コンセプトが`const`/`volatile`修飾を無視していることによる)ため、N4892(C++23 のドラフトの1つ)からは`different-from`という現行の名称に変更された。
20+
21+
22+
## バージョン
23+
### 言語
24+
- C++20
25+
26+
### 処理系
27+
- [Clang](/implementation.md#clang): ??
28+
- [GCC](/implementation.md#gcc): ??
29+
- [ICC](/implementation.md#icc): ??
30+
- [Visual C++](/implementation.md#visual_cpp): ??

reference/ranges/elements_view.md

+9
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ namespace std::ranges {
6060
説明専用コンセプト`has-tuple-element`を次のように定義する。
6161
6262
```cpp
63+
// C++20
6364
template<class T, size_t N>
6465
concept has-tuple-element =
6566
requires(T t) {
@@ -68,12 +69,19 @@ concept has-tuple-element =
6869
typename tuple_element_t<N, T>;
6970
{ get<N>(t) } -> convertible_to<const tuple_element_t<N, T>&>;
7071
};
72+
73+
// C++23
74+
template<class T, size_t N>
75+
concept has-tuple-element =
76+
tuple-like<T> && N < tuple_size_v<T>;
7177
```
7278
* tuple_size[link /reference/tuple/tuple_size.md]
7379
* tuple_element_t[link /reference/tuple/tuple_element.md]
7480
* get[link /reference/tuple/tuple/get.md]
7581
* convertible_to[link /reference/concepts/convertible_to.md]
7682
* remove_reference_t[link /reference/type_traits/remove_reference.md]
83+
* tuple-like[link /reference/tuple/tuple-like.md]
84+
* tuple_size_v[link /reference/tuple/tuple_size.md]
7785

7886
これを用いて、
7987

@@ -161,3 +169,4 @@ three
161169
## 参照
162170
- [N4861 24 Ranges library](https://timsong-cpp.github.io/cppwp/n4861/ranges)
163171
- [C++20 ranges](https://techbookfest.org/product/5134506308665344)
172+
- [P2165R4 Compatibility between `tuple`, `pair` and *tuple-like* objects](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf)

reference/ranges/has-arrow.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# has-arrow
2+
* ranges[meta header]
3+
* concept[meta id-type]
4+
* cpp20[meta cpp]
5+
6+
```cpp
7+
template<class I>
8+
concept has-arrow = // 説明専用コンセプト
9+
input_iterator<I> && (is_pointer_v<I> || requires(I i) { i.operator->(); });
10+
```
11+
* input_iterator[link /reference/iterator/input_iterator.md]
12+
* is_pointer_v[link /reference/type_traits/is_pointer.md]
13+
14+
## 概要
15+
`has-arrow`は、型`I`について[`std::input_iterator`](/reference/iterator/input_iterator.md)を満たす上で、アロー演算子が使用可能であることを表す説明専用コンセプトである。
16+
17+
C++20 のイテレータ定義であるコンセプトたちではアロー演算子を提供することを要求していないため、別途用意されていると考えられる。
18+
19+
20+
## バージョン
21+
### 言語
22+
- C++20
23+
24+
### 処理系
25+
- [Clang](/implementation.md#clang): ??
26+
- [GCC](/implementation.md#gcc): ??
27+
- [ICC](/implementation.md#icc): ??
28+
- [Visual C++](/implementation.md#visual_cpp): ??

0 commit comments

Comments
 (0)