diff --git a/reference/algorithm/clamp.md b/reference/algorithm/clamp.md index f54883f9cc..bf5576db3f 100644 --- a/reference/algorithm/clamp.md +++ b/reference/algorithm/clamp.md @@ -85,3 +85,5 @@ int main() ## 参照 - [N4536 An algorithm to "clamp" a value between a pair of boundary values](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4536.html) - [P0025R0 An algorithm to "clamp" a value between a pair of boundary values (revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0025r0.html) +- [LWG Issue 2688. `clamp` misses preconditions and has extraneous condition on result](https://cplusplus.github.io/LWG/issue2688) + - C++17で、事前条件(`low`は`high`より大きくてはならない)が追加され、戻り値の規定が整理された diff --git a/reference/algorithm/sample.md b/reference/algorithm/sample.md index 928e6e9054..1a2daa547c 100644 --- a/reference/algorithm/sample.md +++ b/reference/algorithm/sample.md @@ -134,3 +134,5 @@ bcd - [N4531 `std::rand` replacement, revision 3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4531.html) - [P0220R0 Adopt Library Fundamentals TS for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r0.html) - [P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html) +- [LWG Issue 2716. Specification of `shuffle` and `sample` disallows lvalue URNGs](https://cplusplus.github.io/LWG/issue2716) + - C++17で、乱数生成器の要件が`remove_reference_t`を通して判定されるよう整理され、左辺値の乱数生成器を渡せることが明確化された diff --git a/reference/algorithm/shuffle.md b/reference/algorithm/shuffle.md index 70a4ff8f78..05d5efd6ac 100644 --- a/reference/algorithm/shuffle.md +++ b/reference/algorithm/shuffle.md @@ -129,5 +129,7 @@ void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRando - [`ranges::shuffle`](/reference/algorithm/ranges_shuffle.md) ## 参照 +- [LWG Issue 2716. Specification of `shuffle` and `sample` disallows lvalue URNGs](https://cplusplus.github.io/LWG/issue2716) + - C++17で、乱数生成器の要件が`remove_reference_t`を通して判定されるよう整理され、左辺値の乱数生成器を渡せることが明確化された - [P0346R1 A `` Nomenclature Tweak](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0346r1.pdf) - URNGをURBGに変更 diff --git a/reference/algorithm/sort_heap.md b/reference/algorithm/sort_heap.md index be74bcd79a..95ce099978 100644 --- a/reference/algorithm/sort_heap.md +++ b/reference/algorithm/sort_heap.md @@ -47,7 +47,7 @@ namespace std { ## 計算量 -最大で N log(N) 回比較する(N == `last - first`) +最大で 2N log(N) 回比較する(N == `last - first`) ## 例 @@ -85,3 +85,5 @@ int main() ## 参照 - [P0879R0 Constexpr for `swap` and `swap` related functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0879r0.html) +- [LWG Issue 2444. Inconsistent complexity for `std::sort_heap`](https://cplusplus.github.io/LWG/issue2444) + - 計算量の上限が「N log(N)回」から「2N log(N)回」に修正された(`sort_heap`はN回の`pop_heap`を行うため)。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/any/any/emplace.md b/reference/any/any/emplace.md index 69cd1cba4b..d0083c493d 100644 --- a/reference/any/any/emplace.md +++ b/reference/any/any/emplace.md @@ -99,3 +99,5 @@ int main() ## 参照 - [LWG Issue 2746. Inconsistency between requirements for `emplace` between `optional` and `variant`](https://cplusplus.github.io/LWG/issue2746) - C++26で、`emplace`の制約が`Requires`(ハードエラー)から`Constraints`(SFINAE)に統一された(cpprefjpでは「テンプレートパラメータ制約」として記載済み) +- [LWG Issue 2754. The `in_place` constructors and `emplace` functions added by P0032R3 don't require `CopyConstructible`](https://cplusplus.github.io/LWG/issue2754) + - C++17で、`emplace`に、格納する型がコピー構築可能であることの要件が追加された diff --git a/reference/any/any/op_constructor.md b/reference/any/any/op_constructor.md index 07e4cddbe7..325b7a9df1 100644 --- a/reference/any/any/op_constructor.md +++ b/reference/any/any/op_constructor.md @@ -145,3 +145,10 @@ int main() - [GCC](/implementation.md#gcc): 7.3 [mark verified] - [ICC](/implementation.md#icc): ?? - [Visual C++](/implementation.md#visual_cpp): ?? + + +## 参照 +- [LWG Issue 2744. `any`'s `in_place` constructors](https://cplusplus.github.io/LWG/issue2744) + - C++17で、`in_place_type_t`を取るコンストラクタの`is_constructible`要件がオーバーロード解決参加条件(SFINAE)へ変更され、`any`に対する`is_constructible`問い合わせが正しい結果を返すようになった +- [LWG Issue 2754. The `in_place` constructors and `emplace` functions added by P0032R3 don't require `CopyConstructible`](https://cplusplus.github.io/LWG/issue2754) + - C++17で、`in_place_type_t`を取るコンストラクタに、格納する型がコピー構築可能であることの要件が追加された diff --git a/reference/any/any_cast.md b/reference/any/any_cast.md index e5d3c40e40..ca10010c98 100644 --- a/reference/any/any_cast.md +++ b/reference/any/any_cast.md @@ -153,4 +153,8 @@ int main() ## 参照 +- [LWG Issue 2768. `any_cast` and move semantics](https://cplusplus.github.io/LWG/issue2768) + - C++17で、`any_cast(any&&)`版がムーブによる取り出しや右辺値参照の取得を行えるよう規定された(LWG 2769の解決に取り込まれた) +- [LWG Issue 2769. Redundant const in the return type of `any_cast(const any&)`](https://cplusplus.github.io/LWG/issue2769) + - C++17で、`any_cast`の戻り値規定から冗長な`const`付与を除き、`U = remove_cv_t>`と`static_cast`を用いる形へ整理された(一時オブジェクトへのダングリング参照取得も防止) - [LWG Issue 3305. `any_cast`](https://cplusplus.github.io/LWG/issue3305) diff --git a/reference/array/array.md b/reference/array/array.md index ff8d6340fa..6daca45679 100644 --- a/reference/array/array.md +++ b/reference/array/array.md @@ -177,3 +177,7 @@ int main() ## 参照 +- [LWG Issue 2590. Aggregate initialization for `std::array`](https://cplusplus.github.io/LWG/issue2590) + - C++17で、`array`がコピーリスト初期化に限らず集成体初期化一般で初期化できることが明確化された(`std::array a{0};`のような直接波カッコ初期化も適格) +- [LWG Issue 2310. Public exposition only member in `std::array`](https://cplusplus.github.io/LWG/issue2310) + - C++17で、`array`が集成体であることを示す説明専用メンバ(`elems`)がpublicである旨が明確化され、`data()`の規定が`addressof(front())`を用いる形に整理された diff --git a/reference/cassert/assert.md b/reference/cassert/assert.md index 69f21a68cb..b844285e69 100644 --- a/reference/cassert/assert.md +++ b/reference/cassert/assert.md @@ -123,6 +123,8 @@ int main() - [What does it mean for C++ that assert takes a scalar argument?](https://groups.google.com/a/isocpp.org/d/topic/std-discussion/6EHDRo1A2EE/discussion) パラメータの式の型についての要件は参照規格であるCの規定によるものであり、「スカラ型」が[C++におけるスカラ型](/reference/type_traits/is_scalar.md)となるのか、あるいはCにおけるスカラ型の範囲に限定されるのか、少なくともC++14時点でははっきりしていない。 - [LWG Issue 2234. `assert()` should allow usage in constant expressions](http://wg21.cmeerw.net/lwg/issue2234) +- [LWG Issue 2559. Error in LWG 2234's resolution](https://cplusplus.github.io/LWG/issue2559) + - C++17で、`assert(E)`が定数部分式となる条件を、`assert`が最後に定義/再定義された時点の`NDEBUG`の状態で判定するよう修正された - [P2264R7 Make `assert()` macro user friendly for C and C++](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2264r7.html) - C++26から、カンマを含む式を条件式として使用できるようになった - [LWG Issue 4454. `assert` should forbid `co_await` and `co_yield`](https://cplusplus.github.io/LWG/issue4454) diff --git a/reference/chrono/time_point/op_minus.md b/reference/chrono/time_point/op_minus.md index 53ab0bd16b..4234217fb0 100644 --- a/reference/chrono/time_point/op_minus.md +++ b/reference/chrono/time_point/op_minus.md @@ -42,11 +42,12 @@ namespace chrono { ## 戻り値 -- (1) +- (1) : 戻り値の型を`CT`として、 ```cpp -return lhs + (-rhs); +return CT(lhs.time_since_epoch() - rhs); ``` +* time_since_epoch[link time_since_epoch.md] - (2) @@ -101,3 +102,5 @@ int main() ## 参照 - [N3469 Constexpr Library Additions: chrono, v3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3469.html) +- [LWG Issue 2739. Issue with `time_point` non-member subtraction with an `unsigned` duration](https://cplusplus.github.io/LWG/issue2739) + - C++17で、(1)の戻り値が`CT(lhs.time_since_epoch() - rhs)`に変更され、符号なし`duration`で負符号化による予期しないオーバーフローが起きないようになった diff --git a/reference/cmath/abs.md b/reference/cmath/abs.md index 5a7ce53373..d8e6b701c9 100644 --- a/reference/cmath/abs.md +++ b/reference/cmath/abs.md @@ -111,3 +111,7 @@ namespace std { - C++23での、一部関数の`constexpr`対応 - [P1467R9 Extended floating-point types and standard names](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html) - C++23で導入された拡張浮動小数点数型への対応として、`float`、`double`、`long double`のオーバーロードを`floating-point-type`のオーバーロードに統合し、拡張浮動小数点数型も扱えるようにした +- [LWG Issue 2192. Validity and return type of `std::abs(0u)` is unclear](https://cplusplus.github.io/LWG/issue2192) + - C++17で、`int`/`long`/`long long`に対するオーバーロード (6)-(8) が追加され、`int`へ整数昇格できない符号なし整数型に対する`abs`の呼び出しが不適格であることが規定された +- [LWG Issue 2735. `std::abs(short)`, `std::abs(signed char)` and others should return `int` instead of `double`](https://cplusplus.github.io/LWG/issue2735) + - C++17で、`abs`は``の整数引数を`double`に変換する追加オーバーロードの対象から除外され、`short`や`signed char`などの引数に対して(整数昇格により)`int`を返すようになった(C++98/Cとの互換性のため) diff --git a/reference/complex/complex/log.md b/reference/complex/complex/log.md index be10de5083..87797145d2 100644 --- a/reference/complex/complex/log.md +++ b/reference/complex/complex/log.md @@ -115,3 +115,5 @@ log( (1,2) ) = (0.804719,1.10715) ## 参照 - [P1383R2 More constexpr for `` and ``](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r2.pdf) - C++26で`constexpr`対応した +- [LWG Issue 2597. `std::log` misspecified for complex numbers](https://cplusplus.github.io/LWG/issue2597) + - 分岐切断上での挙動(負のゼロの扱い)の意味論がCの`clog`と同じであることを意図する、と整理された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/complex/complex/polar.md b/reference/complex/complex/polar.md index 8fdcfc9bcd..8d83edf2d1 100644 --- a/reference/complex/complex/polar.md +++ b/reference/complex/complex/polar.md @@ -8,11 +8,11 @@ namespace std { template complex polar(const T& rho, - const T& theta = 0); // (1) C++03 + const T& theta = T()); // (1) C++03 template constexpr complex polar(const T& rho, - const T& theta = 0); // (1) C++26 + const T& theta = T()); // (1) C++26 } ``` @@ -27,7 +27,7 @@ namespace std { ## 備考 - 規格には、偏角 `theta` の単位については何も記載がない。しかし、この引数の単位がラジアンであることは異論をはさむ余地はないだろう。 実際、本関数の逆関数(の片割れ)とも言える [`arg`](arg.md) の戻り値はラジアンである。 -- コンストラクタのデフォルト引数を踏まえると、偏角 `theta` のデフォルト引数が `T()` ではなく `0` であるのは、規格の誤りであるように思われる。 +- 偏角 `theta` のデフォルト引数は、当初 `0` と規定されていたが、これは規格の誤りであり、LWG Issue 2870 によって `T()`(テンプレートパラメータに依存する値)に修正された。 - `rho` と `theta` に現れる型 `T` は(残念ながら)同じ型でなければならない。(`int` と `double` を渡すなどといったことはできない) 同じ [``](/reference/complex.md) ヘッダの [`pow`](pow.md) や、[`cmath`](/reference/cmath.md) ヘッダの [`atan2`](/reference/cmath/atan2.md) などの関数群は、引数の型が異なっていても簡単に呼び出せるように C++11 でオーバーロードが追加されているため、単なる規格の考慮漏れかもしれない。 @@ -79,5 +79,7 @@ polar(1.0, pi / 4.0) = (0.707107,0.707107) ## 参照 +- [LWG Issue 2870. Default value of parameter theta of polar should be dependent](https://cplusplus.github.io/LWG/issue2870) + - 偏角`theta`のデフォルト引数が`0`から`T()`(テンプレートパラメータに依存する値)に修正された。この修正は欠陥報告(DR)であり、C++17以前にも遡及して適用される - [P1383R2 More constexpr for `` and ``](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r2.pdf) - C++26で`constexpr`対応した diff --git a/reference/complex/complex/sqrt.md b/reference/complex/complex/sqrt.md index b55fdd50bc..b27f004653 100644 --- a/reference/complex/complex/sqrt.md +++ b/reference/complex/complex/sqrt.md @@ -134,3 +134,5 @@ sqrt(-1.0 - 1.0i) = (0.45509,-1.09868) ## 参照 - [P1383R2 More constexpr for `` and ``](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r2.pdf) - C++26で`constexpr`対応した +- [LWG Issue 2597. `std::log` misspecified for complex numbers](https://cplusplus.github.io/LWG/issue2597) + - 分岐切断上での挙動(負のゼロの扱い)の意味論がCの`clog`と同じであることを意図する、と整理された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/concepts/Invoke.md b/reference/concepts/Invoke.md index f7c8619b17..018ecb68d0 100644 --- a/reference/concepts/Invoke.md +++ b/reference/concepts/Invoke.md @@ -84,5 +84,7 @@ C++20 における 2. について、次の文言を項目の最後に追加す - [P0777R1 Treating Unnecessary `decay`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0777r1.pdf) - C++20から`decay_t`を`remove_cvref_t`へ変更。 - [P2136R3 `invoke_r`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2136r3.html) +- [LWG Issue 2219. `INVOKE`-ing a pointer to member with a `reference_wrapper` as the object expression](https://cplusplus.github.io/LWG/issue2219) + - C++17で、メンバポインタに対する第1引数が[`reference_wrapper`](/reference/functional/reference_wrapper.md)の特殊化である場合に、`t1.get()`経由でメンバを呼び出すよう規定された - [LWG Issue 3655. The *INVOKE* operation and union types](https://cplusplus.github.io/LWG/issue3655) - C++23で、メンバポインタの判定を`is_base_of_v`単独から`is_same_v || is_base_of_v`に変更し、共用体(union)型でも正しく扱えるようにした diff --git a/reference/cstddef/offsetof.md b/reference/cstddef/offsetof.md index f8a757c7f6..f10fd6b152 100644 --- a/reference/cstddef/offsetof.md +++ b/reference/cstddef/offsetof.md @@ -51,3 +51,8 @@ offsetof(mystruct,singlechar) is 0 offsetof(mystruct,arraymember) is 1 offsetof(mystruct,anotherchar) is 11 ``` + + +## 参照 +- [LWG Issue 2709. `offsetof` is unnecessarily imprecise](https://cplusplus.github.io/LWG/issue2709) + - C++17で、標準レイアウトでないクラス型に対する`offsetof`の利用が「未定義動作」から「条件付きサポート」に変更された diff --git a/reference/cstdlib/abs.md b/reference/cstdlib/abs.md index 16c7a0c25e..0010c4e811 100644 --- a/reference/cstdlib/abs.md +++ b/reference/cstdlib/abs.md @@ -106,3 +106,5 @@ int main() - C++23での、一部関数の`constexpr`対応 - [P1467R9 Extended floating-point types and standard names](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html) - C++23で導入された拡張浮動小数点数型への対応として、`float`、`double`、`long double`のオーバーロードを`floating-point-type`のオーバーロードに統合し、拡張浮動小数点数型も扱えるようにした +- [LWG Issue 2192. Validity and return type of `std::abs(0u)` is unclear](https://cplusplus.github.io/LWG/issue2192) + - C++17で、`int`へ整数昇格できない符号なし整数型に対する`abs`の呼び出しが不適格であることが規定された diff --git a/reference/deque/deque/erase.md b/reference/deque/deque/erase.md index 327cae3623..59344a140e 100644 --- a/reference/deque/deque/erase.md +++ b/reference/deque/deque/erase.md @@ -26,11 +26,15 @@ constexpr iterator erase(const_iterator first, const_iterator last); // (2) C++2 ## 戻り値 -削除された要素の次の要素を指すイテレータを返す。そのような要素が存在しない場合は、[`end()`](end.md)を返す。さらに、削除された要素以降の要素の数と同じ回数の`T`のムーブ代入演算子が呼ばれる。 +削除された要素の次の要素を指すイテレータを返す。そのような要素が存在しない場合は、[`end()`](end.md)を返す。 + + +## 例外 +`T`の代入演算子が例外を投げる場合を除いて、この関数は例外を投げない。この関数はメモリの確保・解放や要素の構築を行わないため、コンストラクタは呼ばれない。 ## 計算量 -削除された要素の数に対して線形時間(デストラクタ呼び出し)。加えて、`position`と終端位置の間にある要素の数に対してライブラリの実装に依存して線形時間で増加する。 +削除される要素の数と同じ回数の`T`のデストラクタが実行される。加えて`T`の代入演算子が呼ばれるが、その回数は「削除された要素より前にある要素数」と「削除された要素より後にある要素数」のうち少ない方以下となる(`deque`は前後どちらからでも要素を詰められるため)。 ## 例 @@ -112,4 +116,6 @@ int main() ## 参照 - [N2350 Container insert/erase and iterator constness (Revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf) - [LWG Issue 638. `deque` end invalidation during erase](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#638) +- [LWG Issue 2953. LWG 2853 should apply to `deque::erase` too](https://cplusplus.github.io/LWG/issue2953) + - `erase`はメモリ確保・要素構築を行わないため、例外指定からコンストラクタへの言及が削除され`T`の代入演算子のみとされた(`vector::erase`のLWG 2853と同様)。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/deque/deque/shrink_to_fit.md b/reference/deque/deque/shrink_to_fit.md index 0207f3fefd..eb7d288cb1 100644 --- a/reference/deque/deque/shrink_to_fit.md +++ b/reference/deque/deque/shrink_to_fit.md @@ -21,7 +21,7 @@ constexpr void shrink_to_fit(); // (1) C++26 ## 効果 - 確保した未使用のメモリ領域を[`size()`](size.md)に縮小させるというリクエストを行う。 - 実装依存の最適化を許可するために、縮小するという動作は仕様上強制されない。 -- C++17 : コンテナの要素に対する参照、ポインタ、およびイテレータとそれが指す要素への参照は無効となる。 +- C++17 : シーケンスの要素を指すすべての参照・ポインタ・イテレータ、および終端イテレータ(past-the-end iterator)が無効となる。 - C++17 : コピー挿入可能でない型`T`のムーブコンストラクタによる例外を除き、例外が送出された場合この関数は何もしない。 @@ -57,4 +57,6 @@ constexpr void shrink_to_fit(); // (1) C++26 - [LWG Issue 850. Should `shrink_to_fit` apply to `std::deque`?](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#850) - [LWG Issue 2033. Preconditions of `reserve`, `shrink_to_fit`, and `resize` functions](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2033) - [LWG Issue 2223. `shrink_to_fit` effect on iterator validity](https://wg21.cmeerw.net/lwg/issue2223) +- [LWG Issue 2834. Resolution to LWG 2223 is missing wording about end iterators](https://cplusplus.github.io/LWG/issue2834) + - C++17で、終端イテレータ(past-the-end iterator)も無効化されることが明確化された - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/exception/rethrow_if_nested.md b/reference/exception/rethrow_if_nested.md index 7fd4b077a4..fbfd04b2b5 100644 --- a/reference/exception/rethrow_if_nested.md +++ b/reference/exception/rethrow_if_nested.md @@ -17,15 +17,16 @@ namespace std { ## 効果 -型`E`が[`nested_exception`](/reference/exception/nested_exception.md)を継承した型だった場合、以下の処理を行う: +- 型`E`が多相的(polymorphic)なクラス型でない場合、または[`nested_exception`](/reference/exception/nested_exception.md)が`E`のアクセス不能もしくは曖昧な基底クラスである場合、何もしない。 +- そうでなければ、以下を行う: -```cpp -dynamic_cast(e).rethrow_nested() -``` -* nested_exception[link nested_exception.md] -* rethrow_nested()[link nested_exception/rethrow_nested.md] - -そうでなければ何もしない。 + ```cpp + if (auto p = dynamic_cast(addressof(e))) + p->rethrow_nested(); + ``` + * nested_exception[link nested_exception.md] + * rethrow_nested()[link nested_exception/rethrow_nested.md] + * addressof[link /reference/memory/addressof.md] ## 戻り値 @@ -124,3 +125,9 @@ inner ## 参照 - [P3842R2 A conservative fix for constexpr `uncaught_exceptions()` and `current_exception()`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) - C++26の策定中に`constexpr`が追加されたが、本提案文書により巻き戻された (C++29で再検討予定) +- [LWG Issue 2484. `rethrow_if_nested()` is doubly unimplementable](https://cplusplus.github.io/LWG/issue2484) + - 型`E`が多相的でない場合は何もしないこと、および`e`の静的型が[`nested_exception`](nested_exception.md)であるかそこからpublicかつ曖昧さなく派生している場合を対象とすることが規定された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。 C++11時点の規定は「`e`の動的型が`nested_exception`から派生しているか」で判定するとしていたが、非多相なクラス型では動的型を判別する`dynamic_cast`自体が不適格となるため、規定どおりに実装することが不可能だった。したがって処理系は当初からこの修正後の挙動(非多相型では何もしない)を採るしかなく、これと異なる観測可能な挙動が出荷されていたわけではない +- [LWG Issue 2784. Resolution to LWG 2484 is missing "otherwise, no effects" and is hard to parse](https://cplusplus.github.io/LWG/issue2784) + - LWG 2484の解決を整理し、静的型の判定と動的型の判定を分離して、効果をポインタ版`dynamic_cast`とヌルチェックを用いる形に書き直した。あわせて、条件を満たさない場合は何もしないことが明記された + - この修正も欠陥報告(DR)であり、C++11以降に遡及して適用される。 LWG 2484と同じ規定を読みやすく書き換えたものであり、意図された挙動は変わらないため diff --git a/reference/exception/terminate.md b/reference/exception/terminate.md index e1d0d73957..c46df3c16f 100644 --- a/reference/exception/terminate.md +++ b/reference/exception/terminate.md @@ -52,6 +52,10 @@ namespace std { 投げない +## 備考 +例外がアクティブな状態(例外処理中)で[`set_terminate()`](set_terminate.md)によって終了ハンドラが変更された場合、その後に`terminate()`が呼び出されたときにどのハンドラが呼び出されるかは未規定である。例外処理を開始する前に一度だけハンドラを設定する通常の使い方では、常に設定したハンドラが呼び出される。 + + ## 例 ```cpp example #include @@ -81,3 +85,6 @@ terminate called without an active exception - [`set_terminate`](set_terminate.md) - `terminate`が呼び出される状況 - N3337 15.5.1 The `std::terminate()` function `[except.terminal]` +- [LWG Issue 2111. Which unexpected/terminate handler is called from the exception handling runtime?](https://cplusplus.github.io/LWG/issue2111) + - 例外がアクティブな状態でハンドラが変更された場合、どのハンドラが呼び出されるかは未規定と明確化された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。もともと処理系(Itanium ABI等)の実際の挙動が分かれていた領域を未規定として追認したものであり、規定の変更によって処理系の挙動が変わるわけではないため diff --git a/reference/exception/throw_with_nested.md b/reference/exception/throw_with_nested.md index 89256523e8..786a1f69e5 100644 --- a/reference/exception/throw_with_nested.md +++ b/reference/exception/throw_with_nested.md @@ -15,8 +15,15 @@ namespace std { 現在処理中の例外を入れ子にした例外を送出する -## 要件 -型`T`がコピーコンストラクト可能であること。 +## 事前条件 +`U`を [`decay_t`](/reference/type_traits/decay.md)`` として、型`U`がコピー構築可能(*Cpp17CopyConstructible*)の要件を満たすこと。 + + +## 例外 +`U`を [`decay_t`](/reference/type_traits/decay.md)`` とする。 + +- [`is_class_v`](/reference/type_traits/is_class.md)` && !`[`is_final_v`](/reference/type_traits/is_final.md)` && !`[`is_base_of_v`](/reference/type_traits/is_base_of.md)`<`[`nested_exception`](nested_exception.md)`, U>`が`true`である場合、`U`と[`nested_exception`](nested_exception.md)の両方からpublic派生した未規定の型のオブジェクトを、`std::`[`forward`](/reference/utility/forward.md)`(t)`から構築して送出する。 +- そうでない場合、`std::`[`forward`](/reference/utility/forward.md)`(t)`を送出する。 ## 戻り値 @@ -116,3 +123,9 @@ inner ## 参照 - [P3842R2 A conservative fix for constexpr `uncaught_exceptions()` and `current_exception()`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) - C++26の策定中に`constexpr`が追加されたが、本提案文書により巻き戻された (C++29で再検討予定) +- [LWG Issue 2483. `throw_with_nested()` should use `is_final`](https://cplusplus.github.io/LWG/issue2483) + - ラップするかどうかの判定に[`is_final`](/reference/type_traits/is_final.md)による条件が追加され、`final`指定されたクラスも引数に取れるようになった + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。`final`指定されたクラスから派生した型を送出するという元の規定は実装不可能であり、処理系は当初から派生させずにそのまま送出していたため、これと異なる観測可能な挙動が出荷されていたわけではない +- [LWG Issue 2855. `std::throw_with_nested("string_literal")`](https://cplusplus.github.io/LWG/issue2855) + - 判定に[`decay_t`](/reference/type_traits/decay.md)``を用いるよう変更され、文字列リテラルや関数など(配列型・関数型)を渡せることが明確化された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。配列型・関数型を排除していた元の要件は文言上の欠陥であり、処理系は当初から`decay`後の型で動作していたため diff --git a/reference/filesystem/copy_file.md b/reference/filesystem/copy_file.md index 6667ec8663..9c835941f2 100644 --- a/reference/filesystem/copy_file.md +++ b/reference/filesystem/copy_file.md @@ -30,7 +30,7 @@ namespace std::filesystem { - (2) : `return copy_file(from, to,` [`copy_options::none`](copy_options.md)`, ec);` - (3) : - 以下のいずれかの場合にエラーとなる: - - `!`[`is_regular_file`](is_regular_file.md)`(from)` (コピー元のファイルが存在しない) + - `!`[`is_regular_file`](is_regular_file.md)`(from)` (コピー元が通常ファイルでない) - [`exists`](exists.md)`(to) && !`[`is_regular_file`](is_regular_file.md)`(to)` (コピー先に、通常ファイルではないファイルが存在している) - [`exists`](exists.md)`(to) &&` [`equivalent`](equivalent.md)`(from, to)` (コピー先にファイルが存在しており、それがコピー元と等価) - [`exists`](exists.md)`(to) && (options & (`[`copy_options::skip_existing`](copy_options.md) `|` [`copy_options::overwrite_existing`](copy_options.md) `|` [`copy_options::update_existing`](copy_options.md)`)) ==` [`copy_options::none`](copy_options.md) (コピー先にファイルが存在しており、その場合にエラーにならないオプションが指定されていない) @@ -98,5 +98,7 @@ int main() ## 参照 +- [LWG Issue 2712. `copy_file(from, to, ...)` has a number of unspecified error conditions](https://cplusplus.github.io/LWG/issue2712) + - C++17の策定中に、`!is_regular_file(from)`(コピー元が通常ファイルでない)と`exists(to) && !is_regular_file(to)`(コピー先が存在するが通常ファイルでない)の2つがエラー条件として追加された - [LWG Issue 2849. Why does `!is_regular_file(from)` cause `copy_file` to report a "file already exists" error?](https://wg21.cmeerw.net/lwg/issue2849) - [LWG Issue 3014. More `noexcept` issues with filesystem operations](https://wg21.cmeerw.net/lwg/issue3014) diff --git a/reference/filesystem/create_directories.md b/reference/filesystem/create_directories.md index 50bbeaceb6..3e2e499d46 100644 --- a/reference/filesystem/create_directories.md +++ b/reference/filesystem/create_directories.md @@ -71,4 +71,7 @@ int main() ## 参照 +- [LWG Issue 2935. What should `create_directories` do when `p` already exists but is not a directory?](https://cplusplus.github.io/LWG/issue2935) + - `p`が解決する新しいディレクトリが作成された場合のみ`true`を返す旨が明確化され、事後条件`is_directory(p)`が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。元の事後条件`is_directory(p)`は、ディレクトリ作成の失敗後に状態を取得する追加のシステムコールを発行しなければ保証できない意図しない規定であり、処理系は当初から本ページの挙動を採っていたため - [LWG Issue 3014. More `noexcept` issues with filesystem operations](https://wg21.cmeerw.net/lwg/issue3014) diff --git a/reference/filesystem/create_directory.md b/reference/filesystem/create_directory.md index fc54600c6f..1802611d3d 100644 --- a/reference/filesystem/create_directory.md +++ b/reference/filesystem/create_directory.md @@ -86,5 +86,9 @@ int main() ## 参照 +- [LWG Issue 2935. What should `create_directories` do when `p` already exists but is not a directory?](https://cplusplus.github.io/LWG/issue2935) + - 事後条件`is_directory(p)`が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。元の事後条件は、ディレクトリ作成の失敗後に状態を取得する追加のシステムコールを発行しなければ保証できない意図しない規定であり、処理系の挙動は変わらないため + - なお本issueは「パスが既に存在する場合はエラーとしない」形にも緩和したが、これは同じC++20でP1164R1により差し戻された。現在は「既存のディレクトリとして解決されたために作成が失敗した場合はエラーとしない」という本ページの記述となっている - [LWG Issue 3079. LWG 2935 forgot to fix the `existing_p` overloads of `create_directory`](https://cplusplus.github.io/LWG/issue3079) - C++20で、既存アタッチメントを取る`existing_p`版オーバーロードも、指定したパスがすでにディレクトリとして存在する場合にエラーとしないよう修正された diff --git a/reference/filesystem/directory_iterator/op_constructor.md b/reference/filesystem/directory_iterator/op_constructor.md index 8b5d4a044d..76efd2be9a 100644 --- a/reference/filesystem/directory_iterator/op_constructor.md +++ b/reference/filesystem/directory_iterator/op_constructor.md @@ -37,6 +37,7 @@ directory_iterator(directory_iterator&& rhs) noexcept; // (7) - (3), (5) : - (2), (4)に加えて、 - パス`p`へのアクセスが拒否された場合、`options`として[`directory_options::skip_permission_denied`](/reference/filesystem/directory_options.md)が指定されていれば、エラー報告をせず、終端イテレータを構築する +- (2)〜(5) : 構築時にエラーが発生した場合、`*this`は特異な状態にはならず、終端イテレータと等しくなる - (6) : `rhs`を`*this`にコピーする。`rhs`と`*this`が同じオブジェクトである場合はなにもしない - (7) : `rhs`の所有権を`*this`に移動する。`rhs`と`*this`が同じオブジェクトである場合はなにもしない @@ -115,4 +116,6 @@ int main() ## 参照 +- [LWG Issue 2723. Do `directory_iterator` and `recursive_directory_iterator` become the end iterator upon error?](https://cplusplus.github.io/LWG/issue2723) + - C++17の策定中に、構築やインクリメントでエラーが発生した場合、イテレータは特異状態ではなく終端イテレータと等しくなることが規定された(それ以前は処理系間で挙動が分かれていた) - [LWG Issue 3013. `(recursive_)directory_iterator` construction and traversal should not be `noexcept`](https://wg21.cmeerw.net/lwg/issue3013) diff --git a/reference/filesystem/equivalent.md b/reference/filesystem/equivalent.md index b016213a7a..92506f307b 100644 --- a/reference/filesystem/equivalent.md +++ b/reference/filesystem/equivalent.md @@ -19,13 +19,15 @@ namespace std::filesystem { ## 戻り値 -- [`status`](status.md)`(p1)`を`s1`、[`status`](status.md)`(p2)`を`s2`として、 -- `s1 == s2`かつ`p1`と`p2`がファイルシステムとして等価のエンティティに解決される場合、`true`を返し、そうでなければ`false`を返す -- `p1`と`p2`両方のエンティティが存在しない、`p1`と`p2`両方が[`is_other()`](is_other.md)で`true`を返す種別のエンティティである場合、およびファイルシステムでエラーが発生した場合、 (1) では[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出し、 (2) では`ec`にエラー情報が設定されて`false`が返る +- C++17 : [`status`](status.md)`(p1)`を`s1`、[`status`](status.md)`(p2)`を`s2`として、`s1 == s2`かつ`p1`と`p2`がファイルシステムとして等価のエンティティに解決される場合、`true`を返し、そうでなければ`false`を返す +- C++20 : `p1`と`p2`がファイルシステムとして等価のエンティティに解決される場合、`true`を返し、そうでなければ`false`を返す +- エラーとなる条件は以下である。 (1) では[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出し、 (2) では`ec`にエラー情報が設定されて`false`が返る + - C++17 : `p1`と`p2`両方のエンティティが存在しない、または`p1`と`p2`両方が[`is_other()`](is_other.md)で`true`を返す種別のエンティティである場合。およびファイルシステムでエラーが発生した場合 + - C++20 : `p1`と`p2`のいずれか一方でもエンティティが存在しない場合(`!`[`exists`](exists.md)`(p1) || !`[`exists`](exists.md)`(p2)`)。およびファイルシステムでエラーが発生した場合 ## 例外 -- (1) : ファイルシステムがエラーを報告する場合がある。それに加えて、`p1`と`p2`両方のエンティティが存在しない、`p1`と`p2`両方が[`is_other()`](is_other.md)で`true`を返す種別のエンティティである場合もエラーである。エラーが発生した場合は、[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出する +- (1) : ファイルシステムがエラーを報告する場合がある。それに加えて、上記「戻り値」に挙げた条件もエラーである。エラーが発生した場合は、[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出する - (2) : 投げない @@ -76,3 +78,10 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + + +## 参照 +- [LWG Issue 2722. `equivalent` incorrectly specifies throws clause](https://cplusplus.github.io/LWG/issue2722) + - C++17の策定中に、エラー報告の詳細を効果節へ移し、`noexcept`な`error_code`版と例外送出版の双方で正しく扱えるよう整理された +- [LWG Issue 2937. Is `equivalent("existing_thing", "not_existing_thing")` an error?](https://cplusplus.github.io/LWG/issue2937) + - C++20で、`p1`と`p2`のいずれか一方でも存在しない場合はエラーとなるよう変更された(C++17では両方が存在しない場合のみエラー)。あわせて`is_other`による条件と、戻り値の`s1 == s2`の条件が削除された diff --git a/reference/filesystem/file_status/op_constructor.md b/reference/filesystem/file_status/op_constructor.md index 619a7194db..71ebc457d6 100644 --- a/reference/filesystem/file_status/op_constructor.md +++ b/reference/filesystem/file_status/op_constructor.md @@ -62,3 +62,8 @@ int main() - [Clang](/implementation.md#clang): - [GCC](/implementation.md#gcc): 4.8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + + +## 参照 +- [LWG Issue 2787. [file_status.cons] doesn't match class definition](https://cplusplus.github.io/LWG/issue2787) + - C++17の策定中に、非explicitなデフォルトコンストラクタ(1)と、explicitな引数付きコンストラクタ(2)という形にクラス定義と整合するよう整理された diff --git a/reference/filesystem/is_empty.md b/reference/filesystem/is_empty.md index 8e79fb66ef..b5415992b7 100644 --- a/reference/filesystem/is_empty.md +++ b/reference/filesystem/is_empty.md @@ -79,4 +79,6 @@ int main() ## 参照 +- [LWG Issue 2672. Should `is_empty` use `error_code` in its specification?](https://cplusplus.github.io/LWG/issue2672) + - C++17の策定中に、`error_code`を取るシグネチャにおいて、内部で呼ぶ各操作でエラーが発生した場合は`false`を返し`ec`にエラーを伝播することが明確化された - [LWG Issue 3013. `(recursive_)directory_iterator` construction and traversal should not be `noexcept`](https://wg21.cmeerw.net/lwg/issue3013) diff --git a/reference/filesystem/path/op_append_assign.md b/reference/filesystem/path/op_append_assign.md index b12201f572..51d3b2eb68 100644 --- a/reference/filesystem/path/op_append_assign.md +++ b/reference/filesystem/path/op_append_assign.md @@ -180,3 +180,8 @@ h : "D:bar" ### 備考 - GCC 8.1 (SVN) の`operator/=`では、ルートディレクトリを持つパスを加算すると、左辺が削除されないバグがある - [Bug 84159 - `filesystem::path::operator/=` with has root directory path](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84159) + + +## 参照 +- [LWG Issue 2664. `operator/` (and other append) semantics not useful if argument has root](https://cplusplus.github.io/LWG/issue2664) + - ルート名を持つパスを追加すると`"c:\x" / "d:\y"`が`"c:\x\d:\y"`のような無意味な結果になる問題が指摘された。この issue 自体は事前条件`!p.has_root_name()`を課す解決を提案していたが、最終的なC++17では事前条件とはせず、`p`が絶対パスであるか異なるルート名を持つ場合は`p`で置き換える、という上記の効果として規定された diff --git a/reference/filesystem/path/op_constructor.md b/reference/filesystem/path/op_constructor.md index 0406fc101b..5dc6eef353 100644 --- a/reference/filesystem/path/op_constructor.md +++ b/reference/filesystem/path/op_constructor.md @@ -203,5 +203,9 @@ int main() ## 参照 +- [LWG Issue 2707. `path` construction and assignment should have `string_type&&` overloads](https://cplusplus.github.io/LWG/issue2707) + - C++17の策定中に、一時的なネイティブ文字列からムーブできるよう`string_type&&`を受け取るコンストラクタ(4)が追加された +- [LWG Issue 2711. `path` is convertible from approximately everything under the sun](https://cplusplus.github.io/LWG/issue2711) + - C++17の策定中に、`EcharT`がエンコード文字型であること、および`Source`が`basic_string`の特殊化か文字イテレータであることを要求する制約が追加され、任意の型からの意図しない変換が排除された - [LWG Issue 3244. Constraints for `Source` in [fs.path.req] insufficiently constrainty](https://cplusplus.github.io/LWG/issue3244) - C++20で、`Source`型の制約に「`path`以外の型であること」という条件が追加され、`path`を`Source`として渡した際の循環参照が排除された diff --git a/reference/filesystem/path/root_directory.md b/reference/filesystem/path/root_directory.md index 5a64996d77..fa895e6ccc 100644 --- a/reference/filesystem/path/root_directory.md +++ b/reference/filesystem/path/root_directory.md @@ -76,3 +76,8 @@ int main() - [Clang](/implementation.md#clang): - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): 2017 Update 7 [mark verified] + + +## 参照 +- [LWG Issue 2667. `path::root_directory()` description is confusing](https://cplusplus.github.io/LWG/issue2667) + - C++17の策定中に、「ルートディレクトリが slash name で構成される場合、slash は戻り値の文字列から除外される」という、文法定義と矛盾する文言が削除された(戻り値の規定自体は変わっていない) diff --git a/reference/filesystem/permissions.md b/reference/filesystem/permissions.md index c5feedc314..833b159f93 100644 --- a/reference/filesystem/permissions.md +++ b/reference/filesystem/permissions.md @@ -20,7 +20,9 @@ namespace std::filesystem { ## 効果 -- POSIX環境では、[`fchmodat()`](http://ja.manpages.org/fchmodat/2)関数を使用して、パス`to`のファイルに対する権限を設定する +`opts`で指定されたアクションを、パス`p`が解決するファイルに対して適用する。ただし、`p`がシンボリックリンクであり、かつ`opts`に[`perm_options::nofollow`](perm_options.md)が設定されている場合は、シンボリックリンク自体に対して適用する。 + +- POSIX環境では、[`fchmodat()`](http://ja.manpages.org/fchmodat/2)関数を使用して権限を設定する - (2) は、権限オプションとして[`perm_options::replace`](perm_options.md)が使用される @@ -29,7 +31,8 @@ namespace std::filesystem { ## 例外 -- (1) : ファイルシステムがエラーを報告する場合がある。エラーが発生した場合は、[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出する +- (1), (3) : ファイルシステムがエラーを報告する場合がある。エラーが発生した場合は、[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出する + - (3) は狭い契約(`opts`に`perm_options`の`replace`・`add`・`remove`のうち正確に1つが含まれること)を持つため`noexcept`ではない - (2) : 投げない @@ -69,3 +72,10 @@ int main() ## 関連項目 - [`status()`](status.md) - [`symlink_status()`](symlink_status.md) + + +## 参照 +- [LWG Issue 2719. `permissions` function should not be `noexcept` due to narrow contract](https://cplusplus.github.io/LWG/issue2719) + - C++17の策定中に、狭い契約(`opts`に`perm_options`の`replace`・`add`・`remove`のうち正確に1つが含まれること)を持つため、`perm_options`と`error_code`を取る版(3)から`noexcept`が外された +- [LWG Issue 2720. `permissions` function incorrectly specified for symlinks](https://cplusplus.github.io/LWG/issue2720) + - C++17の策定中に、シンボリックリンク自体を対象とするか解決先を対象とするかを制御する方向へ整理された(本issue自体は`perms::resolve_symlinks`を`perms::symlink_nofollow`へ置き換えるもので、最終的なC++17ではP0492R2により[`perm_options`](perm_options.md)`::nofollow`となった) diff --git a/reference/filesystem/recursive_directory_iterator/depth.md b/reference/filesystem/recursive_directory_iterator/depth.md index 24c85b9853..c2bfa72ddc 100644 --- a/reference/filesystem/recursive_directory_iterator/depth.md +++ b/reference/filesystem/recursive_directory_iterator/depth.md @@ -13,6 +13,10 @@ int depth() const; ディレクトリの深さを取得する。 +## 事前条件 +`*this`がデリファレンス可能であること。終端イテレータや、インクリメントによって無効化されたコピーはデリファレンス可能ではない。 + + ## 戻り値 横断している現在のディレクトリの深さを返す。 @@ -64,3 +68,7 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + +## 参照 +- [LWG Issue 2704. `recursive_directory_iterator`'s members should require '`*this` is dereferenceable'](https://cplusplus.github.io/LWG/issue2704) + - C++17の策定中に、`options`/`depth`/`recursion_pending`/`pop`/`disable_recursion_pending`は`*this`がデリファレンス可能であることを要求する(そうでない場合は未定義動作)と規定された diff --git a/reference/filesystem/recursive_directory_iterator/disable_recursion_pending.md b/reference/filesystem/recursive_directory_iterator/disable_recursion_pending.md index e0c8afcd2c..f42471897c 100644 --- a/reference/filesystem/recursive_directory_iterator/disable_recursion_pending.md +++ b/reference/filesystem/recursive_directory_iterator/disable_recursion_pending.md @@ -13,6 +13,10 @@ void disable_recursion_pending(); 再帰を止める。 +## 事前条件 +`*this`がデリファレンス可能であること。終端イテレータや、インクリメントによって無効化されたコピーはデリファレンス可能ではない。 + + ## 効果 ディレクトリパスを指している際にこの関数を呼び出すことによって、そのディレクトリに入らないようになる。 @@ -67,3 +71,7 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + +## 参照 +- [LWG Issue 2704. `recursive_directory_iterator`'s members should require '`*this` is dereferenceable'](https://cplusplus.github.io/LWG/issue2704) + - C++17の策定中に、`options`/`depth`/`recursion_pending`/`pop`/`disable_recursion_pending`は`*this`がデリファレンス可能であることを要求する(そうでない場合は未定義動作)と規定された diff --git a/reference/filesystem/recursive_directory_iterator/options.md b/reference/filesystem/recursive_directory_iterator/options.md index a3ebee98a6..b68a5ae0ff 100644 --- a/reference/filesystem/recursive_directory_iterator/options.md +++ b/reference/filesystem/recursive_directory_iterator/options.md @@ -14,6 +14,10 @@ directory_options options() const; 走査オプションを取得する。 +## 事前条件 +`*this`がデリファレンス可能であること。終端イテレータや、インクリメントによって無効化されたコピーはデリファレンス可能ではない。 + + ## 戻り値 コンストラクタで設定されたオプションを返す。コンストラクタで明示的にオプションを指定していない場合は、[`directory_options::none`](/reference/filesystem/directory_options.md)を返す。 @@ -54,3 +58,7 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + +## 参照 +- [LWG Issue 2704. `recursive_directory_iterator`'s members should require '`*this` is dereferenceable'](https://cplusplus.github.io/LWG/issue2704) + - C++17の策定中に、`options`/`depth`/`recursion_pending`/`pop`/`disable_recursion_pending`は`*this`がデリファレンス可能であることを要求する(そうでない場合は未定義動作)と規定された diff --git a/reference/filesystem/recursive_directory_iterator/pop.md b/reference/filesystem/recursive_directory_iterator/pop.md index 36eeffff49..3dc0fbb55e 100644 --- a/reference/filesystem/recursive_directory_iterator/pop.md +++ b/reference/filesystem/recursive_directory_iterator/pop.md @@ -14,6 +14,10 @@ void pop(std::error_code& ec); そのディレクトリの走査を中断する。 +## 事前条件 +`*this`がデリファレンス可能であること。終端イテレータや、インクリメントによって無効化されたコピーはデリファレンス可能ではない。 + + ## 効果 [`depth()`](depth.md) `== 0`の場合は、`*this`に終端イテレータを代入する。そうでない場合は、そのディレクトリの走査を終了し、親ディレクトリに戻る。 @@ -72,3 +76,7 @@ int main() ## 参照 - [LWG Issue `recursive_directory_iterator::pop` must invalidate](https://wg21.cmeerw.net/lwg/issue3067) +- [LWG Issue 2704. `recursive_directory_iterator`'s members should require '`*this` is dereferenceable'](https://cplusplus.github.io/LWG/issue2704) + - C++17の策定中に、`options`/`depth`/`recursion_pending`/`pop`/`disable_recursion_pending`は`*this`がデリファレンス可能であることを要求する(そうでない場合は未定義動作)と規定された +- [LWG Issue 2706. Error reporting for `recursive_directory_iterator::pop()` is under-specified](https://cplusplus.github.io/LWG/issue2706) + - C++17の策定中に、`increment`と一貫したエラー報告のため`pop(error_code&)`オーバーロードが追加された diff --git a/reference/filesystem/recursive_directory_iterator/recursion_pending.md b/reference/filesystem/recursive_directory_iterator/recursion_pending.md index fac527fd28..bcbdee9437 100644 --- a/reference/filesystem/recursive_directory_iterator/recursion_pending.md +++ b/reference/filesystem/recursive_directory_iterator/recursion_pending.md @@ -13,6 +13,10 @@ bool recursion_pending() const; 再帰しないかどうかが未決定かを確認する。 +## 事前条件 +`*this`がデリファレンス可能であること。終端イテレータや、インクリメントによって無効化されたコピーはデリファレンス可能ではない。 + + ## 戻り値 [`disable_recursion_pending()`](disable_recursion_pending.md)がそのディレクトリに対して呼ばれていなければ`true`、そうでなければ`false`を返す。 @@ -67,3 +71,7 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + +## 参照 +- [LWG Issue 2704. `recursive_directory_iterator`'s members should require '`*this` is dereferenceable'](https://cplusplus.github.io/LWG/issue2704) + - C++17の策定中に、`options`/`depth`/`recursion_pending`/`pop`/`disable_recursion_pending`は`*this`がデリファレンス可能であることを要求する(そうでない場合は未定義動作)と規定された diff --git a/reference/filesystem/remove_all.md b/reference/filesystem/remove_all.md index f9131f3ed5..366ad032a7 100644 --- a/reference/filesystem/remove_all.md +++ b/reference/filesystem/remove_all.md @@ -20,14 +20,20 @@ namespace std::filesystem { ## 効果 -- パス`p`のコンテンツを、再帰的に削除する +- パス`p`が存在する場合、そのコンテンツを再帰的に削除し、続けてパス`p`自体を削除する - POSIX環境では、それぞれのコンテンツの削除に、[`remove()`](https://web.archive.org/web/20230207183630/http://linuxjm.osdn.jp/html/LDP_man-pages/man3/remove.3.html)関数を使用する +- `p`がシンボリックリンクである場合、リンクが解決するファイルではなく、シンボリックリンク自体が削除される ## 戻り値 削除されたファイルの数が返る +## 事後条件 +- `!`[`exists`](exists.md)`(`[`symlink_status`](symlink_status.md)`(p))` + - [`symlink_status()`](symlink_status.md)を介して判定されるため(シンボリックリンクを解決しない)、リンク先が存在しないシンボリックリンク(ダングリングリンク)も削除される必要がある + + ## 例外 - (1) : ファイルシステムがエラーを報告する場合がある。エラーが発生した場合は、[`std::filesystem::filesystem_error`](filesystem_error.md)例外を送出する - (2) : ディレクトリを走査する際にメモリ確保に失敗した場合、例外を送出する可能性がある @@ -85,4 +91,6 @@ int main() ## 参照 +- [LWG Issue 2721. `remove_all` has incorrect post conditions](https://cplusplus.github.io/LWG/issue2721) + - C++17の策定中に、事後条件が`!exists(symlink_status(p))`に修正され、ダングリングなシンボリックリンク自体も削除されることが明確化された - [LWG Issue 3014. More `noexcept` issues with filesystem operations](https://wg21.cmeerw.net/lwg/issue3014) diff --git a/reference/filesystem/status.md b/reference/filesystem/status.md index 89ebf2e971..12c1ea2ee9 100644 --- a/reference/filesystem/status.md +++ b/reference/filesystem/status.md @@ -120,3 +120,8 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + + +## 参照 +- [LWG Issue 2728. `status(p).permissions()` and `symlink_status(p).permissions()` are not specified](https://cplusplus.github.io/LWG/issue2728) + - C++17の策定中に、返される[`file_status`](file_status.md)にファイルの権限(`perms`)が設定されることが規定された diff --git a/reference/filesystem/symlink_status.md b/reference/filesystem/symlink_status.md index e6523a95b0..2eafaf2800 100644 --- a/reference/filesystem/symlink_status.md +++ b/reference/filesystem/symlink_status.md @@ -118,3 +118,8 @@ int main() - [Clang](/implementation.md#clang): 7.0 [mark verified] - [GCC](/implementation.md#gcc): 8.1 [mark verified] - [Visual C++](/implementation.md#visual_cpp): + + +## 参照 +- [LWG Issue 2728. `status(p).permissions()` and `symlink_status(p).permissions()` are not specified](https://cplusplus.github.io/LWG/issue2728) + - C++17の策定中に、返される[`file_status`](file_status.md)にファイルの権限(`perms`)が設定されることが規定された diff --git a/reference/fstream/basic_filebuf.md b/reference/fstream/basic_filebuf.md index 615d679cd6..a0aba75938 100644 --- a/reference/fstream/basic_filebuf.md +++ b/reference/fstream/basic_filebuf.md @@ -31,14 +31,16 @@ Cの`FILE*`に対する入出力関数を使って実装される。 | `wfilebuf` | `wchar_t`型。ワイド文字列として使用する。 | | +## メンバ関数 + ### 構築・破棄 -| 名前 | 説明 | 対応バージョン | -|---------------------------------------------------|----------------|----------------| -| [`(constructor)`](basic_filebuf/op_constructor.md) | コンストラクタ | | -| [`(destructor)`](basic_filebuf/op_destructor.md) | デストラクタ | | -| `operator=` | ムーブ代入 | C++11 | -| `swap` | 値の交換 | C++11 | +| 名前 | 説明 | 対応バージョン | +|----------------------------------------------------|----------------|----------------| +| [`(constructor)`](basic_filebuf/op_constructor.md) | コンストラクタ | | +| [`(destructor)`](basic_filebuf/op_destructor.md) | デストラクタ | | +| [`operator=`](basic_filebuf/op_assign.md) | ムーブ代入 | C++11 | +| [`swap`](basic_filebuf/swap.md) | 値の交換 | C++11 | - コピーコンストラクタとコピー代入演算子は`delete`宣言されている。 @@ -63,16 +65,23 @@ Cの`FILE*`に対する入出力関数を使って実装される。 | 名前 | 説明 | 対応バージョン | |---------------------------------------------|----------------|----------------| -| `imbue` | ロケールを設定する (protected virtual) | | -| `setbuf` | バッファ領域を与える (protected virtual) | | -| `seekoff` | 相対指定での位置移動 (protected virtual) | | -| `seekpos` | 絶対指定での位置移動 (protected virtual) | | -| `sync` | 出力列の同期 (protected virtual) | | -| `uflow` | (protected virtual) | -| `underflow` | (protected virtual) | -| `showmanyc` | ブロックせずに読み取れると期待される文字数を得る (protected virtual) | | -| `pbackfail` | 1文字を入力列に戻す (protected virtual) | | -| `overflow` | (protected virtual) | +| [`imbue`](basic_filebuf/imbue.md) | ロケールを設定する | | +| [`setbuf`](basic_filebuf/setbuf.md) | バッファ領域を与える | | +| [`seekoff`](basic_filebuf/seekoff.md) | 相対指定での位置移動 | | +| [`seekpos`](basic_filebuf/seekpos.md) | 絶対指定での位置移動 | | +| [`sync`](basic_filebuf/sync.md) | 出力列の同期 | | +| [`uflow`](basic_filebuf/uflow.md) | ファイルから文字を読み込み、読み取り位置を進める | | +| [`underflow`](basic_filebuf/underflow.md) | ファイルから文字を読み込む | | +| [`showmanyc`](basic_filebuf/showmanyc.md) | ブロックせずに読み取れると期待される文字数を得る | | +| [`pbackfail`](basic_filebuf/pbackfail.md) | 1文字を入力列に戻す | | +| [`overflow`](basic_filebuf/overflow.md) | 蓄えられた文字をファイルへ書き出す | | + + +## 非メンバ関数 + +| 名前 | 説明 | 対応バージョン | +|------------------------------------------|----------------------|----------------| +| [`swap`](basic_filebuf/swap_free.md) | 2つのオブジェクトの値を交換する | C++11 | ## メンバ型 @@ -86,5 +95,51 @@ Cの`FILE*`に対する入出力関数を使って実装される。 | `native_handle_type` | ネイティブハンドルの型 [処理系定義] | C++26 | -## 参照 +## 例 +```cpp example +#include +#include + +int main() +{ + // ファイルへ書き込む + { + std::filebuf buf; + buf.open("test.txt", std::ios_base::out); + buf.sputn("Hello", 5); + } + + // ファイルから読み込む + std::filebuf buf; + buf.open("test.txt", std::ios_base::in); + + for (std::filebuf::int_type c = buf.sbumpc(); + c != std::filebuf::traits_type::eof(); + c = buf.sbumpc()) { + std::cout << static_cast(c); + } + std::cout << std::endl; +} +``` +* std::filebuf[color ff0000] +* buf.open[link basic_filebuf/open.md] +* buf.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] +* traits_type::eof()[link /reference/string/char_traits/eof.md] + +### 出力 +``` +Hello +``` + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 - [`basic_streambuf`](../streambuf/basic_streambuf.md) +- [`basic_fstream`](basic_fstream.md) +- [`basic_ifstream`](basic_ifstream.md) +- [`basic_ofstream`](basic_ofstream.md) diff --git a/reference/fstream/basic_filebuf/imbue.md b/reference/fstream/basic_filebuf/imbue.md new file mode 100644 index 0000000000..6c34cffcfb --- /dev/null +++ b/reference/fstream/basic_filebuf/imbue.md @@ -0,0 +1,81 @@ +# imbue +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual void imbue(const locale& loc); // (1) C++03 + void imbue(const locale& loc) override; // (1) C++17 +``` +* locale[link /reference/locale/locale.md] + +## 概要 +ロケールを設定する。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`pubimbue()`](/reference/streambuf/basic_streambuf/pubimbue.md)を通して間接的に呼び出される。 + + +## 事前条件 +ファイルが先頭以外の位置にあり、かつ現在のロケールの[`codecvt`](/reference/locale/codecvt.md)ファセットの`encoding()`が状態依存のエンコーディングを示す場合、そのファセットが`loc`の対応するファセットと同じであること。 + + +## 効果 +この呼び出し以降に挿入・抽出される文字が、次に`imbue`が呼び出されるまで`loc`に従って変換されるようにする。 + + +## 戻り値 +なし + + +## 備考 +この関数は、それまでに変換した文字の再変換を必要とする場合がある。またそのために、処理系がファイルの元の内容を復元できることを必要とする場合がある。 + + +## 例 +```cpp example +#include +#include +#include + +// basic_filebufを継承して、protectedなimbueの呼び出しを観測する +struct my_filebuf : std::filebuf { +protected: + void imbue(const std::locale& loc) override + { + std::cout << "imbue" << std::endl; + std::filebuf::imbue(loc); + } +}; + +int main() +{ + my_filebuf buf; + buf.open("test.txt", std::ios_base::out); + + // pubimbue()を通してimbue()が呼ばれる + buf.pubimbue(std::locale::classic()); +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* imbue[color ff0000] +* buf.open[link open.md] +* buf.pubimbue[link /reference/streambuf/basic_streambuf/pubimbue.md] +* std::locale[link /reference/locale/locale.md] +* std::locale::classic()[link /reference/locale/locale/classic.md] + +### 出力 +``` +imbue +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::imbue`](/reference/streambuf/basic_streambuf/imbue.md) +- [`basic_streambuf::pubimbue`](/reference/streambuf/basic_streambuf/pubimbue.md) +- [`codecvt`](/reference/locale/codecvt.md) diff --git a/reference/fstream/basic_filebuf/op_assign.md b/reference/fstream/basic_filebuf/op_assign.md new file mode 100644 index 0000000000..5dfbc214fb --- /dev/null +++ b/reference/fstream/basic_filebuf/op_assign.md @@ -0,0 +1,80 @@ +# operator= +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] +* cpp11[meta cpp] + +```cpp +basic_filebuf& operator=(const basic_filebuf&) = delete; // (1) C++11 +basic_filebuf& operator=(basic_filebuf&& rhs); // (2) C++11 +``` + +## 概要 +- (1) : コピー代入。この演算子は`delete`定義されており、`basic_filebuf`オブジェクトはコピーできない +- (2) : ムーブ代入。`rhs`が管理していたファイルの所有権を`*this`に移動する + + +## 効果 +- (2) : [`close()`](close.md)を呼び出したのち、`rhs`からムーブ代入する + + +## 事後条件 +- (2) : `*this`は、`rhs`からムーブ構築された場合と同じ観測可能な状態を持つ。詳細は[コンストラクタ](op_constructor.md)を参照 + - `rhs`は、いかなるファイルも参照しない状態([`is_open()`](is_open.md)`== false`)となる + + +## 戻り値 +- (2) : `*this` + + +## 例 +```cpp example +#include +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("Hello", 5); + } + + std::filebuf a; + a.open("test.txt", std::ios_base::in); + + std::filebuf b; + b = std::move(a); // aが開いていたファイルをbに移動する + + std::cout << std::boolalpha + << a.is_open() << ' ' + << b.is_open() << std::endl; + + std::cout << static_cast(b.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* out.open[link open.md] +* a.open[link open.md] +* a.is_open()[link is_open.md] +* b.is_open()[link is_open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* b.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] +* std::move[link /reference/utility/move.md] + +### 出力 +``` +false true +H +``` + +## バージョン +### 言語 +- C++11 + + +## 関連項目 +- [`basic_filebuf`のコンストラクタ](op_constructor.md) +- [`basic_filebuf::swap`](swap.md) diff --git a/reference/fstream/basic_filebuf/op_constructor.md b/reference/fstream/basic_filebuf/op_constructor.md index 294413282d..f707d339e9 100644 --- a/reference/fstream/basic_filebuf/op_constructor.md +++ b/reference/fstream/basic_filebuf/op_constructor.md @@ -5,37 +5,93 @@ * function[meta id-type] ```cpp -basic_filebuf(); // (1) -basic_filebuf(basic_filebuf&& rhs); // (2) C++11 +basic_filebuf(); // (1) C++98 +basic_filebuf(const basic_filebuf&) = delete; // (2) C++11 +basic_filebuf(basic_filebuf&& rhs); // (3) C++11 ``` ## 概要 オブジェクトを構築する。 +- (1) : デフォルト構築。ファイルを開いていない状態のオブジェクトを構築する +- (2) : コピー構築。この関数は`delete`定義されており、`basic_filebuf`オブジェクトはコピーできない +- (3) : ムーブ構築。`rhs`が開いていたファイルの所有権を`*this`に移動する + + ## 効果 +- (1) : 基底クラスを[`basic_streambuf()`](/reference/streambuf/basic_streambuf/op_constructor.md)で初期化する +- (3) : + - `*this`のシーケンスポインタ([`eback()`](/reference/streambuf/basic_streambuf/eback.md), [`gptr()`](/reference/streambuf/basic_streambuf/gptr.md), [`egptr()`](/reference/streambuf/basic_streambuf/egptr.md), [`pbase()`](/reference/streambuf/basic_streambuf/pbase.md), [`pptr()`](/reference/streambuf/basic_streambuf/pptr.md), [`epptr()`](/reference/streambuf/basic_streambuf/epptr.md))が`rhs`の持っていた値を得るかどうかは、処理系定義である + - それらの値を得るかどうかに関わらず、構築後の`*this`と`rhs`は(存在する場合)別々のバッファを参照する + - `*this`は構築前に`rhs`が参照していたファイルを参照し、`rhs`は構築後にいかなるファイルも参照しない + - `rhs`のオープンモード、ロケール、その他の状態もコピーされる -- (1): 基底クラスのコンストラクタ`basic_streambuf()`を呼び出す。 -- (2): ムーブ構築する。構築完了後、以下の状態になる。 ## 事後条件 -- (1) - - 構築完了後、`is_open() == false`となる。 -- (2): コンストラクタ呼び出し前の`rhs`を`rhs_p`、コンストラクタ呼び出し後の`rhs`を`rhs_a`と表記する。 - - `is_open() == rhs_p.is_open()` - - `rhs_p.is_open() == false` +- (1) : [`is_open()`](is_open.md)`== false` +- (3) : コンストラクタ呼び出し前の`rhs`の状態を`rhs_p`、呼び出し後の`rhs`の状態を`rhs_a`と表記する + - [`is_open()`](is_open.md)`== rhs_p.`[`is_open()`](is_open.md) + - `rhs_a.`[`is_open()`](is_open.md)`== false` - `gptr() - eback() == rhs_p.gptr() - rhs_p.eback()` - `egptr() - eback() == rhs_p.egptr() - rhs_p.eback()` - `pptr() - pbase() == rhs_p.pptr() - rhs_p.pbase()` - `epptr() - pbase() == rhs_p.epptr() - rhs_p.pbase()` - - `eback() != rhs_a.eback()` (`eback()`が非`nullptr`の場合のみ) - - `gptr() != rhs_a.gptr()` (`gptr()`が非`nullptr`の場合のみ) - - `egptr() != rhs_a.egptr()` (`egptr()`が非`nullptr`の場合のみ) + - `eback()`が非ヌルの場合、`eback() != rhs_a.eback()` + - `gptr()`が非ヌルの場合、`gptr() != rhs_a.gptr()` + - `egptr()`が非ヌルの場合、`egptr() != rhs_a.egptr()` + - `pbase()`が非ヌルの場合、`pbase() != rhs_a.pbase()` + - `pptr()`が非ヌルの場合、`pptr() != rhs_a.pptr()` + - `epptr()`が非ヌルの場合、`epptr() != rhs_a.epptr()` + + +## 例 +```cpp example +#include +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("Hello", 5); + } + + // (1) ファイルを開いていない状態で構築する + std::filebuf a; + std::cout << std::boolalpha << a.is_open() << std::endl; + + a.open("test.txt", std::ios_base::in); -## 実装例 + // (3) aが開いていたファイルをbに移動する + std::filebuf b = std::move(a); + + std::cout << a.is_open() << ' ' << b.is_open() << std::endl; + std::cout << static_cast(b.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* out.open[link open.md] +* a.open[link open.md] +* a.is_open()[link is_open.md] +* b.is_open()[link is_open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* b.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] +* std::move[link /reference/utility/move.md] + +### 出力 +``` +false +false true +H +``` ## バージョン ### 言語 - C++98 -- C++11: ムーブコンストラクタの追加 -## 参照 + +## 関連項目 +- [`basic_filebuf::operator=`](op_assign.md) +- [`basic_filebuf::open`](open.md) diff --git a/reference/fstream/basic_filebuf/op_destructor.md b/reference/fstream/basic_filebuf/op_destructor.md index 2c076d3a99..799819d8d2 100644 --- a/reference/fstream/basic_filebuf/op_destructor.md +++ b/reference/fstream/basic_filebuf/op_destructor.md @@ -5,22 +5,19 @@ * function[meta id-type] ```cpp -~basic_filebuf() override; +virtual ~basic_filebuf(); // (1) C++98 ``` ## 概要 オブジェクトを破棄する。 ## 効果 - -`close()`を呼び出す。 +[`close()`](close.md)を呼び出す。 そこで例外が発生した場合、catchして何も行わない(再送出しない)。 -## 事後条件 - ## 実装例 ```cpp -~basic_filebuf() override { +virtual ~basic_filebuf() { try { close(); } catch (...) { @@ -38,4 +35,3 @@ ### 言語 - C++98 -## 参照 diff --git a/reference/fstream/basic_filebuf/open.md b/reference/fstream/basic_filebuf/open.md index b14df4e705..56c582e9b6 100644 --- a/reference/fstream/basic_filebuf/open.md +++ b/reference/fstream/basic_filebuf/open.md @@ -94,7 +94,8 @@ int main() ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取る`open`(4)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された - [LWG Issue 2943. Problematic specification of the wide version of `basic_filebuf::open`](https://cplusplus.github.io/LWG/issue2943) diff --git a/reference/fstream/basic_filebuf/overflow.md b/reference/fstream/basic_filebuf/overflow.md new file mode 100644 index 0000000000..f0cc47cd14 --- /dev/null +++ b/reference/fstream/basic_filebuf/overflow.md @@ -0,0 +1,101 @@ +# overflow +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual int_type overflow(int_type c = traits::eof()); // (1) C++03 + int_type overflow(int_type c = traits::eof()) override; // (1) C++17 +``` + +## 概要 +出力部分列の領域を消費し切った際に、蓄えられた文字をファイルへ書き出す。 + +このメンバ関数は`protected`であり、[`sputc()`](/reference/streambuf/basic_streambuf/sputc.md)などのpublicメンバ関数を通して間接的に呼び出される。 + + +## 効果 +[`basic_streambuf::overflow(c)`](/reference/streambuf/basic_streambuf/overflow.md)の規定に従う。ただし`basic_filebuf`では「文字を消費する」動作が、まず以下のように変換を行ったうえで実施される。 + +```cpp +charT* b = pbase(); +charT* p = pptr(); +const charT* end; +char xbuf[XSIZE]; +char* xbuf_end; +codecvt_base::result r = + a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end); +``` +* pbase()[link /reference/streambuf/basic_streambuf/pbase.md] +* pptr()[link /reference/streambuf/basic_streambuf/pptr.md] +* codecvt_base::result[link /reference/locale/codecvt_base.md] +* a_codecvt.out[link /reference/locale/codecvt/out.md.nolink] + +ここで`a_codecvt`は、このストリームバッファに設定されているロケールの[`codecvt`](/reference/locale/codecvt.md)ファセットである。変換結果`r`に応じて、以下のように動作する。 + +- `r == codecvt_base::error`の場合、失敗する +- `r == codecvt_base::noconv`の場合、`b`から`p`の直前までの文字を出力する +- `r == codecvt_base::partial`の場合、`xbuf`から`xbuf_end`までの文字をファイルへ出力し、`end`から`p`までの文字を使って繰り返す。出力に失敗した場合は(繰り返さずに)失敗する +- それ以外の場合、`xbuf`から`xbuf_end`までを出力し、出力に失敗したら失敗する。この時点で`b != p`かつ`b == end`である(`xbuf`の領域が足りない)場合は、`XSIZE`を増やして最初から繰り返す + +その後、観測可能なチェックポイントを設定する。 + + +## 戻り値 +- 成功した場合、[`Traits::not_eof`](/reference/string/char_traits/not_eof.md)`(c)` +- 失敗した場合、[`Traits::eof()`](/reference/string/char_traits/eof.md) + +[`is_open()`](is_open.md)`== false`である場合、この関数は常に失敗する。 + + +## 例 +```cpp example +#include +#include + +// basic_filebufを継承して、protectedなoverflowの呼び出しを観測する +struct my_filebuf : std::filebuf { +protected: + int_type overflow(int_type c) override + { + std::cout << "overflow" << std::endl; + return std::filebuf::overflow(c); + } +}; + +int main() +{ + my_filebuf buf; + buf.open("test.txt", std::ios_base::out); + + // 出力領域を持たない状態で書き込むため、overflow()が呼ばれる + buf.sputc('A'); + + // 書き出しのために、closeからもoverflow()が呼ばれる + buf.close(); +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* overflow[color ff0000] +* buf.open[link open.md] +* buf.close()[link close.md] +* buf.sputc[link /reference/streambuf/basic_streambuf/sputc.md] + +### 出力例 +``` +overflow +overflow +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_filebuf::sync`](sync.md) +- [`basic_filebuf::close`](close.md) +- [`basic_streambuf::overflow`](/reference/streambuf/basic_streambuf/overflow.md) +- [`codecvt`](/reference/locale/codecvt.md) diff --git a/reference/fstream/basic_filebuf/pbackfail.md b/reference/fstream/basic_filebuf/pbackfail.md new file mode 100644 index 0000000000..992ebc88fa --- /dev/null +++ b/reference/fstream/basic_filebuf/pbackfail.md @@ -0,0 +1,93 @@ +# pbackfail +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual int_type pbackfail(int_type c = traits::eof()); // (1) C++03 + int_type pbackfail(int_type c = traits::eof()) override; // (1) C++17 +``` + +## 概要 +1文字を入力列に戻す。 + +このメンバ関数は`protected`であり、[`sputbackc()`](/reference/streambuf/basic_streambuf/sputbackc.md)や[`sungetc()`](/reference/streambuf/basic_streambuf/sungetc.md)を通して間接的に呼び出される。 + + +## 効果 +可能であれば、`c`が指定する文字を入力シーケンスへ戻す。以下の3つのいずれかの方法で行われる。 + +- [`Traits::eq_int_type`](/reference/string/char_traits/eq_int_type.md)`(c, `[`Traits::eof()`](/reference/string/char_traits/eof.md)`)`が`false`を返し、この関数が戻し位置(putback position)を利用可能にでき、かつ[`Traits::eq`](/reference/string/char_traits/eq.md)`(`[`Traits::to_char_type`](/reference/string/char_traits/to_char_type.md)`(c), `[`gptr()`](/reference/streambuf/basic_streambuf/gptr.md)`[-1])`が`true`を返す場合、入力シーケンスの次ポインタ[`gptr()`](/reference/streambuf/basic_streambuf/gptr.md)をデクリメントする +- [`Traits::eq_int_type`](/reference/string/char_traits/eq_int_type.md)`(c, `[`Traits::eof()`](/reference/string/char_traits/eof.md)`)`が`false`を返し、この関数が戻し位置を利用可能にでき、かつ戻し位置への代入が許される場合、入力シーケンスの次ポインタをデクリメントし、その位置に`c`を格納する +- [`Traits::eq_int_type`](/reference/string/char_traits/eq_int_type.md)`(c, `[`Traits::eof()`](/reference/string/char_traits/eof.md)`)`が`true`を返し、かつ入力シーケンスに戻し位置があるか、この関数が戻し位置を利用可能にできる場合、入力シーケンスの次ポインタ[`gptr()`](/reference/streambuf/basic_streambuf/gptr.md)をデクリメントする + +複数の方法で成功しうる場合、どの方法が選択されるかは未規定である。 + + +## 戻り値 +- 上記1番目・2番目の方法で成功した場合、`c` +- 上記3番目の方法で成功した場合、[`Traits::not_eof`](/reference/string/char_traits/not_eof.md)`(c)` +- 失敗した場合、[`Traits::eof()`](/reference/string/char_traits/eof.md) + + +## 備考 +[`is_open()`](is_open.md)`== false`である場合、この関数は常に失敗する。 + +この関数は、文字を入力シーケンスへ直接戻すわけではない。また、この関数の呼び出しによって利用可能な戻し位置の数が変化することがある。 + + +## 例 +```cpp example +#include +#include + +// basic_filebufを継承して、protectedなpbackfailの呼び出しを観測する +struct my_filebuf : std::filebuf { +protected: + int_type pbackfail(int_type c) override + { + std::cout << "pbackfail" << std::endl; + return std::filebuf::pbackfail(c); + } +}; + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("AB", 2); + } + + my_filebuf buf; + buf.open("test.txt", std::ios_base::in); + + // 1文字も読み取っていない状態で戻そうとするため、pbackfail()が呼ばれて失敗する + std::cout << (buf.sungetc() == std::filebuf::traits_type::eof()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* pbackfail[color ff0000] +* out.open[link open.md] +* buf.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.sungetc()[link /reference/streambuf/basic_streambuf/sungetc.md] +* traits_type::eof()[link /reference/string/char_traits/eof.md] + +### 出力 +``` +pbackfail +1 +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::pbackfail`](/reference/streambuf/basic_streambuf/pbackfail.md) +- [`basic_streambuf::sputbackc`](/reference/streambuf/basic_streambuf/sputbackc.md) +- [`basic_streambuf::sungetc`](/reference/streambuf/basic_streambuf/sungetc.md) diff --git a/reference/fstream/basic_filebuf/seekoff.md b/reference/fstream/basic_filebuf/seekoff.md new file mode 100644 index 0000000000..68bd6c05ba --- /dev/null +++ b/reference/fstream/basic_filebuf/seekoff.md @@ -0,0 +1,106 @@ +# seekoff +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual pos_type + seekoff(off_type off, + ios_base::seekdir way, + ios_base::openmode which = ios_base::in | ios_base::out); // (1) C++03 + pos_type + seekoff(off_type off, + ios_base::seekdir way, + ios_base::openmode which = ios_base::in | ios_base::out) override; // (1) C++17 +``` +* ios_base::seekdir[link /reference/ios/ios_base/type-seekdir.md] +* ios_base::openmode[link /reference/ios/ios_base/type-openmode.md] + +## 概要 +相対位置指定でファイル位置を移動する。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`pubseekoff()`](/reference/streambuf/basic_streambuf/pubseekoff.md)を通して間接的に呼び出される。 + + +## 効果 +現在のロケールの[`codecvt`](/reference/locale/codecvt.md)ファセットの`encoding()`の値を`width`とする。 + +- [`is_open()`](is_open.md)`== false`である場合、もしくは`off != 0 && width <= 0`である場合、位置指定操作は失敗する +- そうでない場合、`way != `[`ios_base::cur`](/reference/ios/ios_base/type-seekdir.md)もしくは`off != 0`であり、かつ直前の操作が出力であった場合は、出力シーケンスを更新し、シフト状態を戻すシーケンス(unshift sequence)を書き込む +- 続いて新しい位置へ移動する。`width > 0`の場合は[`std::fseek`](/reference/cstdio/fseek.md.nolink)`(file, width * off, whence)`を、そうでない場合は[`std::fseek`](/reference/cstdio/fseek.md.nolink)`(file, 0, whence)`を呼び出す + +`whence`の値は、`way`の値に応じて以下のように決まる。 + +| `way`の値 | `stdio`での対応する値 | +|-----------|-----------------------| +| [`ios_base::beg`](/reference/ios/ios_base/type-seekdir.md) | `SEEK_SET` | +| [`ios_base::cur`](/reference/ios/ios_base/type-seekdir.md) | `SEEK_CUR` | +| [`ios_base::end`](/reference/ios/ios_base/type-seekdir.md) | `SEEK_END` | + + +## 戻り値 +可能であれば、移動結果のストリーム位置を保持する`pos_type`オブジェクトを構築して返す。 + +位置指定操作が失敗した場合、または移動結果のストリーム位置を`pos_type`オブジェクトで表現できない場合は、`pos_type(off_type(-1))`を返す。 + + +## 備考 +「直前の操作が出力であった」とは、直前の仮想関数の操作が[`overflow`](overflow.md)であったか、もしくはput領域が空でないことを意味する。 + +「シフト状態を戻すシーケンスを書き込む」とは、`width`が負である場合に[`codecvt`](/reference/locale/codecvt.md)ファセットの`unshift()`を呼び出し、その結果得られたシーケンスを出力することを意味する。 + + +## 例 +```cpp example +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("ABCDE", 5); + } + + std::filebuf buf; + buf.open("test.txt", std::ios_base::in); + + // 先頭から2文字目へ移動する + buf.pubseekoff(2, std::ios_base::beg); + std::cout << static_cast(buf.sbumpc()) << std::endl; + + // 現在位置から1文字進める + buf.pubseekoff(1, std::ios_base::cur); + std::cout << static_cast(buf.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* out.open[link open.md] +* buf.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.pubseekoff[link /reference/streambuf/basic_streambuf/pubseekoff.md] +* buf.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] + +### 出力 +``` +C +E +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_filebuf::seekpos`](seekpos.md) +- [`basic_streambuf::seekoff`](/reference/streambuf/basic_streambuf/seekoff.md) +- [`basic_streambuf::pubseekoff`](/reference/streambuf/basic_streambuf/pubseekoff.md) + + +## 参照 +- [LWG Issue 2473. `basic_filebuf`'s relation to C `FILE` semantics](https://cplusplus.github.io/LWG/issue2473) + - `seekoff`と`seekpos`のCの対応関数(`fseek`/`fsetpos`)との関係が整理された diff --git a/reference/fstream/basic_filebuf/seekpos.md b/reference/fstream/basic_filebuf/seekpos.md new file mode 100644 index 0000000000..6e868be966 --- /dev/null +++ b/reference/fstream/basic_filebuf/seekpos.md @@ -0,0 +1,59 @@ +# seekpos +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual pos_type + seekpos(pos_type sp, + ios_base::openmode which = ios_base::in | ios_base::out); // (1) C++03 + pos_type + seekpos(pos_type sp, + ios_base::openmode which = ios_base::in | ios_base::out) override; // (1) C++17 +``` +* ios_base::openmode[link /reference/ios/ios_base/type-openmode.md] + +## 概要 +絶対位置指定でファイル位置を移動する。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`pubseekpos()`](/reference/streambuf/basic_streambuf/pubseekpos.md)を通して間接的に呼び出される。 + + +## 事前条件 +`sp`が、同一ファイルに対する位置指定関数([`seekoff`](seekoff.md)または`seekpos`)の以前の成功した呼び出しによって取得された値であること。そうでない場合、動作は未定義である。 + + +## 効果 +可能であれば、`sp`に格納された位置に対応するようファイル位置を変更する。ファイル位置の変更は以下のように行われる。ここで`om`は最後の[`open()`](open.md)呼び出しに渡されたオープンモードである。 + +1. `(om & `[`ios_base::out`](/reference/ios/ios_base/type-openmode.md)`) != 0`の場合、出力シーケンスを更新し、シフト状態を戻すシーケンス(unshift sequence)を書き込む。 +2. あたかも[`std::fsetpos`](/reference/cstdio/fsetpos.md)を呼び出したかのようにファイル位置を`sp`に設定する。 +3. `(om & `[`ios_base::in`](/reference/ios/ios_base/type-openmode.md)`) != 0`の場合、入力シーケンスを更新する。 + +[`is_open()`](is_open.md)が`false`を返す場合、この操作は失敗する。また、`sp`が無効なストリーム位置である場合、またはこの関数がどちらのシーケンスも位置指定しない場合も、位置指定操作は失敗する。 + + +## 戻り値 +成功した場合は`sp`を返す。そうでない場合は`pos_type(off_type(-1))`を返す。 + + +## 備考 +引数`which`は使用されない。入力・出力シーケンスのどちらを更新するかは、最後の[`open()`](open.md)呼び出しに渡されたオープンモードのみによって決まる。 + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::seekpos`](/reference/streambuf/basic_streambuf/seekpos.md) +- [`basic_streambuf::pubseekpos`](/reference/streambuf/basic_streambuf/pubseekpos.md) + + +## 参照 +- [LWG Issue 2473. `basic_filebuf`'s relation to C `FILE` semantics](https://cplusplus.github.io/LWG/issue2473) + - `seekpos`が`fsetpos`を呼び出したかのようにファイル位置を設定する、と明確化された(CのFILEの更新モードにおける読み書き間の位置指定制約に整合させるため) + - この修正は欠陥報告(DR)であり、C++98に遡及して適用される。`seekoff`には`fseek`の言及があるのに`seekpos`にはCの対応関数の言及が欠けていた規定漏れの補完であり、処理系は当初からCの`FILE`のセマンティクスに従って実装されていたため diff --git a/reference/fstream/basic_filebuf/setbuf.md b/reference/fstream/basic_filebuf/setbuf.md new file mode 100644 index 0000000000..a1c0f3cf85 --- /dev/null +++ b/reference/fstream/basic_filebuf/setbuf.md @@ -0,0 +1,73 @@ +# setbuf +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual basic_streambuf* + setbuf(char_type* s, streamsize n); // (1) C++03 + basic_streambuf* + setbuf(char_type* s, streamsize n) override; // (1) C++17 +``` +* basic_streambuf[link /reference/streambuf/basic_streambuf.md] +* streamsize[link /reference/ios/type-streamsize.md] + +## 概要 +バッファ領域を与える。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`pubsetbuf()`](/reference/streambuf/basic_streambuf/pubsetbuf.md)を通して間接的に呼び出される。 + + +## 効果 +そのストリームに対して入出力が行われる前に`setbuf(0, 0)`が呼び出された場合、ストリームはバッファリングされない状態(unbuffered)になる。それ以外の場合の結果は処理系定義である。 + +「バッファリングされない」とは、[`pbase()`](/reference/streambuf/basic_streambuf/pbase.md)と[`pptr()`](/reference/streambuf/basic_streambuf/pptr.md)が常にヌルポインタを返し、ファイルへの出力が可能な限り速やかに行われることを意味する。 + + +## 戻り値 +規格に規定はない。主要な処理系は`this`を返す。 + + +## 例 +```cpp example +#include +#include + +int main() +{ + std::filebuf buf; + + // 入出力を行う前に呼び出すことで、バッファリングを無効化する + buf.pubsetbuf(nullptr, 0); + + buf.open("test.txt", std::ios_base::out); + buf.sputn("Hello", 5); + + // バッファリングされていないため、この時点で既にファイルへ書き込まれている + std::filebuf in; + in.open("test.txt", std::ios_base::in); + std::cout << static_cast(in.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* buf.pubsetbuf[link /reference/streambuf/basic_streambuf/pubsetbuf.md] +* buf.open[link open.md] +* in.open[link open.md] +* buf.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* in.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] + +### 出力 +``` +H +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::setbuf`](/reference/streambuf/basic_streambuf/setbuf.md) +- [`basic_streambuf::pubsetbuf`](/reference/streambuf/basic_streambuf/pubsetbuf.md) diff --git a/reference/fstream/basic_filebuf/showmanyc.md b/reference/fstream/basic_filebuf/showmanyc.md new file mode 100644 index 0000000000..ae1a86cd1b --- /dev/null +++ b/reference/fstream/basic_filebuf/showmanyc.md @@ -0,0 +1,74 @@ +# showmanyc +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual streamsize showmanyc(); // (1) C++03 + streamsize showmanyc() override; // (1) C++17 +``` +* streamsize[link /reference/ios/type-streamsize.md] + +## 概要 +ブロックせずに読み取れると期待される文字数を得る。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`in_avail()`](/reference/streambuf/basic_streambuf/in_avail.md)を通して間接的に呼び出される。 + + +## 効果 +[`basic_streambuf::showmanyc()`](/reference/streambuf/basic_streambuf/showmanyc.md)と同じ動作をする。 + + +## 戻り値 +[`basic_streambuf::showmanyc()`](/reference/streambuf/basic_streambuf/showmanyc.md)と同じ。 + + +## 備考 +処理系は、入力シーケンスからさらに文字を読み取れるかどうかを判断できる場合、この関数シグニチャに対するオーバーライド定義を提供してもよい。 + + +## 例 +```cpp example +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("ABCDE", 5); + } + + std::filebuf buf; + buf.open("test.txt", std::ios_base::in); + + // get領域に文字を読み込む + buf.sgetc(); + + // 読み込み済みの領域に残っている文字数を得る + std::cout << (buf.in_avail() > 0) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* out.open[link open.md] +* buf.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.sgetc()[link /reference/streambuf/basic_streambuf/sgetc.md] +* buf.in_avail()[link /reference/streambuf/basic_streambuf/in_avail.md] + +### 出力 +``` +1 +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::showmanyc`](/reference/streambuf/basic_streambuf/showmanyc.md) +- [`basic_streambuf::in_avail`](/reference/streambuf/basic_streambuf/in_avail.md) diff --git a/reference/fstream/basic_filebuf/swap.md b/reference/fstream/basic_filebuf/swap.md new file mode 100644 index 0000000000..965be47966 --- /dev/null +++ b/reference/fstream/basic_filebuf/swap.md @@ -0,0 +1,76 @@ +# swap +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] +* cpp11[meta cpp] + +```cpp +void swap(basic_filebuf& rhs); // (1) C++11 +``` + +## 概要 +`rhs`との間で、値を交換する。 + + +## 効果 +`*this`と`rhs`の状態を交換する。開いているファイル、オープンモード、ロケール、バッファのいずれもが交換対象である。 + + +## 戻り値 +なし + + +## 例 +```cpp example +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("a.txt", std::ios_base::out); + out.sputn("A", 1); + } + { + std::filebuf out; + out.open("b.txt", std::ios_base::out); + out.sputn("B", 1); + } + + std::filebuf a; + a.open("a.txt", std::ios_base::in); + + std::filebuf b; + b.open("b.txt", std::ios_base::in); + + a.swap(b); + + std::cout << static_cast(a.sbumpc()) << std::endl; + std::cout << static_cast(b.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* a.swap[color ff0000] +* out.open[link open.md] +* a.open[link open.md] +* b.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* a.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] +* b.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] + +### 出力 +``` +B +A +``` + +## バージョン +### 言語 +- C++11 + + +## 関連項目 +- [`swap` (非メンバ関数)](swap_free.md) +- [`basic_filebuf::operator=`](op_assign.md) diff --git a/reference/fstream/basic_filebuf/swap_free.md b/reference/fstream/basic_filebuf/swap_free.md new file mode 100644 index 0000000000..d26ba69cd4 --- /dev/null +++ b/reference/fstream/basic_filebuf/swap_free.md @@ -0,0 +1,78 @@ +# swap (非メンバ関数) +* fstream[meta header] +* std[meta namespace] +* function template[meta id-type] +* cpp11[meta cpp] + +```cpp +namespace std { + template + void swap(basic_filebuf& x, + basic_filebuf& y); // (1) C++11 +} +``` + +## 概要 +2つの`basic_filebuf`オブジェクトの値を交換する。 + + +## 効果 +`x.`[`swap`](swap.md)`(y)`と等価 + + +## 戻り値 +なし + + +## 例 +```cpp example +#include +#include + +int main() +{ + { + std::filebuf out; + out.open("a.txt", std::ios_base::out); + out.sputn("A", 1); + } + { + std::filebuf out; + out.open("b.txt", std::ios_base::out); + out.sputn("B", 1); + } + + std::filebuf a; + a.open("a.txt", std::ios_base::in); + + std::filebuf b; + b.open("b.txt", std::ios_base::in); + + std::swap(a, b); + + std::cout << static_cast(a.sbumpc()) << std::endl; + std::cout << static_cast(b.sbumpc()) << std::endl; +} +``` +* std::swap[color ff0000] +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* out.open[link open.md] +* a.open[link open.md] +* b.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* a.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] +* b.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] + +### 出力 +``` +B +A +``` + +## バージョン +### 言語 +- C++11 + + +## 関連項目 +- [`basic_filebuf::swap`](swap.md) diff --git a/reference/fstream/basic_filebuf/sync.md b/reference/fstream/basic_filebuf/sync.md new file mode 100644 index 0000000000..9ecd9c72d7 --- /dev/null +++ b/reference/fstream/basic_filebuf/sync.md @@ -0,0 +1,42 @@ +# sync +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual int sync(); // (1) C++03 + int sync() override; // (1) C++17 +``` + +## 概要 +制御対象のシーケンスとファイルを同期する(出力をフラッシュする)。 + +このメンバ関数は`protected`であり、[`std::basic_streambuf`](/reference/streambuf/basic_streambuf.md)の`public`メンバ関数[`pubsync()`](/reference/streambuf/basic_streambuf/pubsync.md)を通して間接的に呼び出される。 + + +## 効果 +put領域が存在する場合、`basic_filebuf`の[`overflow`](overflow.md)を呼び出して文字をファイルに書き込み、その後あたかも[`std::fflush`](/reference/cstdio/fflush.md)`(file)`を呼び出したかのようにファイルをフラッシュする。 + +get領域が存在する場合の効果は、処理系定義である。 + + +## 戻り値 +失敗した場合は`-1`を返す。それ以外の場合は`0`を返す。何を失敗とみなすかは、このクラスが定める。 + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_streambuf::sync`](/reference/streambuf/basic_streambuf/sync.md) +- [`basic_streambuf::pubsync`](/reference/streambuf/basic_streambuf/pubsync.md) + + +## 参照 +- [LWG Issue 2473. `basic_filebuf`'s relation to C `FILE` semantics](https://cplusplus.github.io/LWG/issue2473) + - `sync`があたかも`fflush(file)`を呼び出したかのようにファイルをフラッシュする、と明確化された(CのFILEにおける入出力操作の相互作用に整合させるため) + - この修正は欠陥報告(DR)であり、C++98に遡及して適用される。`seekoff`には`fseek`の言及があるのに`sync`にはCの対応関数の言及が欠けていた規定漏れの補完であり、処理系は当初からCの`FILE`のセマンティクスに従って実装されていたため diff --git a/reference/fstream/basic_filebuf/uflow.md b/reference/fstream/basic_filebuf/uflow.md new file mode 100644 index 0000000000..a27be42cef --- /dev/null +++ b/reference/fstream/basic_filebuf/uflow.md @@ -0,0 +1,81 @@ +# uflow +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual int_type uflow(); // (1) C++03 + int_type uflow() override; // (1) C++17 +``` + +## 概要 +入力部分列に文字がない場合に、ファイルから文字を読み込み、読み取り位置を進める。 + +このメンバ関数は`protected`であり、[`sbumpc()`](/reference/streambuf/basic_streambuf/sbumpc.md)などのpublicメンバ関数を通して間接的に呼び出される。 + + +## 効果 +[`basic_streambuf::uflow()`](/reference/streambuf/basic_streambuf/uflow.md)の規定に従う。ただし`basic_filebuf`では、入力からの文字の読み取りが[`underflow()`](underflow.md)と同じ方法([`codecvt`](/reference/locale/codecvt.md)ファセットによる変換)で行われる。 + + +## 戻り値 +[`basic_streambuf::uflow()`](/reference/streambuf/basic_streambuf/uflow.md)と同じ。読み取りに成功した場合はその文字を、失敗した場合は[`Traits::eof()`](/reference/string/char_traits/eof.md)を返す。 + + +## 例 +```cpp example +#include +#include + +// basic_filebufを継承して、protectedなuflowの呼び出しを観測する +struct my_filebuf : std::filebuf { +protected: + int_type uflow() override + { + std::cout << "uflow" << std::endl; + return std::filebuf::uflow(); + } +}; + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("AB", 2); + } + + my_filebuf buf; + buf.open("test.txt", std::ios_base::in); + + // get領域が空なので、uflow()が呼ばれる + std::cout << static_cast(buf.sbumpc()) << std::endl; + + // 既に読み込み済みの領域から読み取るため、uflow()は呼ばれない + std::cout << static_cast(buf.sbumpc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* uflow[color ff0000] +* out.open[link open.md] +* buf.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.sbumpc()[link /reference/streambuf/basic_streambuf/sbumpc.md] + +### 出力 +``` +uflow +A +B +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_filebuf::underflow`](underflow.md) +- [`basic_streambuf::uflow`](/reference/streambuf/basic_streambuf/uflow.md) diff --git a/reference/fstream/basic_filebuf/underflow.md b/reference/fstream/basic_filebuf/underflow.md new file mode 100644 index 0000000000..528f8dc898 --- /dev/null +++ b/reference/fstream/basic_filebuf/underflow.md @@ -0,0 +1,98 @@ +# underflow +* fstream[meta header] +* std[meta namespace] +* basic_filebuf[meta class] +* function[meta id-type] + +```cpp +protected: + virtual int_type underflow(); // (1) C++03 + int_type underflow() override; // (1) C++17 +``` + +## 概要 +入力部分列に文字がない場合に、ファイルから文字を読み込む。 + +このメンバ関数は`protected`であり、[`sgetc()`](/reference/streambuf/basic_streambuf/sgetc.md)などのpublicメンバ関数を通して間接的に呼び出される。 + + +## 効果 +[`basic_streambuf::underflow()`](/reference/streambuf/basic_streambuf/underflow.md)の規定に従う。ただし`basic_filebuf`では、入力シーケンスからの文字の読み取りが、ファイルから内部バッファ(下記の`extern_buf`)へ読み込み、それを以下のように変換したかのように行われる。 + +```cpp +char extern_buf[XSIZE]; +const char* extern_end; +charT intern_buf[ISIZE]; +charT* intern_end; +codecvt_base::result r = + a_codecvt.in(state, extern_buf, extern_buf+XSIZE, extern_end, + intern_buf, intern_buf+ISIZE, intern_end); +``` +* codecvt_base::result[link /reference/locale/codecvt_base.md] +* a_codecvt.in[link /reference/locale/codecvt/in.md.nolink] + +ここで`a_codecvt`は、このストリームバッファに設定されているロケールの[`codecvt`](/reference/locale/codecvt.md)ファセットである。 + +この変換は、`intern_buf`と`intern_end`の間の各文字に対応する位置(`fpos_t`)をクラスが復元できるような方法で行われる。`r`の値が`a_codecvt.in()`が`intern_buf`の領域を使い切ったことを示す場合は、より大きな`intern_buf`で再試行する。 + + +## 戻り値 +[`basic_streambuf::underflow()`](/reference/streambuf/basic_streambuf/underflow.md)と同じ。読み取りに成功した場合は次に読み取られる文字を、失敗した場合は[`Traits::eof()`](/reference/string/char_traits/eof.md)を返す。 + + +## 例 +```cpp example +#include +#include + +// basic_filebufを継承して、protectedなunderflowの呼び出しを観測する +struct my_filebuf : std::filebuf { +protected: + int_type underflow() override + { + std::cout << "underflow" << std::endl; + return std::filebuf::underflow(); + } +}; + +int main() +{ + { + std::filebuf out; + out.open("test.txt", std::ios_base::out); + out.sputn("AB", 2); + } + + my_filebuf buf; + buf.open("test.txt", std::ios_base::in); + + // get領域が空なので、underflow()が呼ばれる + std::cout << static_cast(buf.sgetc()) << std::endl; + + // 既に読み込み済みなので、underflow()は呼ばれない + std::cout << static_cast(buf.sgetc()) << std::endl; +} +``` +* std::filebuf[link /reference/fstream/basic_filebuf.md] +* underflow[color ff0000] +* out.open[link open.md] +* buf.open[link open.md] +* out.sputn[link /reference/streambuf/basic_streambuf/sputn.md] +* buf.sgetc()[link /reference/streambuf/basic_streambuf/sgetc.md] + +### 出力 +``` +underflow +A +A +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`basic_filebuf::uflow`](uflow.md) +- [`basic_streambuf::underflow`](/reference/streambuf/basic_streambuf/underflow.md) +- [`codecvt`](/reference/locale/codecvt.md) diff --git a/reference/fstream/basic_fstream/op_constructor.md b/reference/fstream/basic_fstream/op_constructor.md index b39c152a69..a095a31c48 100644 --- a/reference/fstream/basic_fstream/op_constructor.md +++ b/reference/fstream/basic_fstream/op_constructor.md @@ -113,7 +113,8 @@ basic_fstream::basic_fstream(basic_fstream&& rhs) ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3130. §[input.output] needs many `addressof`](https://wg21.cmeerw.net/lwg/issue3130) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取るコンストラクタ(5)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/fstream/basic_fstream/open.md b/reference/fstream/basic_fstream/open.md index 8dcf35e35d..8fee67b41b 100644 --- a/reference/fstream/basic_fstream/open.md +++ b/reference/fstream/basic_fstream/open.md @@ -79,6 +79,7 @@ int main() ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取る`open`(4)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/fstream/basic_ifstream/op_constructor.md b/reference/fstream/basic_ifstream/op_constructor.md index 96ac417a27..a6c52ff9db 100644 --- a/reference/fstream/basic_ifstream/op_constructor.md +++ b/reference/fstream/basic_ifstream/op_constructor.md @@ -113,7 +113,8 @@ basic_ifstream::basic_ifstream(basic_ifstream&& rhs) ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3130. §[input.output] needs many `addressof`](https://wg21.cmeerw.net/lwg/issue3130) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取るコンストラクタ(5)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/fstream/basic_ifstream/open.md b/reference/fstream/basic_ifstream/open.md index 0db4c034a2..b49885d806 100644 --- a/reference/fstream/basic_ifstream/open.md +++ b/reference/fstream/basic_ifstream/open.md @@ -79,6 +79,7 @@ int main() ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取る`open`(4)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/fstream/basic_ofstream/op_constructor.md b/reference/fstream/basic_ofstream/op_constructor.md index 449bba4ca5..893a376416 100644 --- a/reference/fstream/basic_ofstream/op_constructor.md +++ b/reference/fstream/basic_ofstream/op_constructor.md @@ -112,7 +112,8 @@ basic_ofstream::basic_ofstream(basic_ofstream&& rhs) ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3130. §[input.output] needs many `addressof`](https://wg21.cmeerw.net/lwg/issue3130) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取るコンストラクタ(5)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/fstream/basic_ofstream/open.md b/reference/fstream/basic_ofstream/open.md index 31d3681505..1840920ffe 100644 --- a/reference/fstream/basic_ofstream/open.md +++ b/reference/fstream/basic_ofstream/open.md @@ -78,6 +78,7 @@ int main() ## 参照 -- [LGW issue 2676. Provide filesystem::path overloads for File-based streams](https://wg21.cmeerw.net/lwg/issue2676) +- [LWG Issue 2676. Provide `filesystem::path` overloads for File-based streams](https://cplusplus.github.io/LWG/issue2676) + - C++17で、`filesystem::path`および`filesystem::path::value_type*`を受け取るオーバーロードが追加された(`basic_filebuf`は`open`のみ、`basic_ifstream`/`basic_ofstream`/`basic_fstream`はコンストラクタと`open`) - [LWG Issue 3430. `std::fstream` & co. should be constructible from `string_view`](https://cplusplus.github.io/LWG/issue3430) - C++23で、`filesystem::path`を受け取る`open`(4)が、`path`へ暗黙変換可能な型による高コストな変換を防ぐため、`is_same_v`を制約とする制約付きテンプレートに変更された diff --git a/reference/functional/function/op_constructor.md b/reference/functional/function/op_constructor.md index afb86abd60..da32bd6d9c 100644 --- a/reference/functional/function/op_constructor.md +++ b/reference/functional/function/op_constructor.md @@ -56,6 +56,9 @@ function(allocator_arg_t, const Alloc& alloc, F f); // (10) C++17 - (5) : - C++11 - `F`は、パラメータとして`ArgTypes...`型をとり、戻り値として`R`型を返す関数ポインタ、メンバ関数ポインタ、メンバ変数ポインタ、または関数オブジェクトであること + - C++17 + - `F`が*Lvalue-Callable*であること。すなわち、式[*INVOKE*](/reference/concepts/Invoke.md)`(`[`declval`](/reference/utility/declval.md)`(),` [`declval`](/reference/utility/declval.md)`()...)`が適格であること + - 左辺値参照として呼び出せることが要求されるため、右辺値参照修飾(`&&`修飾)された関数呼び出し演算子のみを持つ型は格納できない - C++23 - `F`が`function`ではないこと - `FD`は、パラメータとして`ArgTypes...`型をとり、戻り値として`R`型を返す関数ポインタ、メンバ関数ポインタ、メンバ変数ポインタ、または関数オブジェクトであること @@ -86,8 +89,26 @@ function(allocator_arg_t, const Alloc& alloc, F f); // (10) C++17 ## 例外 -- (3), (8) : `f`が[`reference_wrapper`](/reference/functional/reference_wrapper.md)か関数ポインタを保持している場合は、例外を投げるべきではない。`f`が関数オブジェクトを保持している場合は、そのコピーコンストラクタが[`bad_alloc`](/reference/new/bad_alloc.md)やその他の例外を投げる可能性がある。 -- (10) : `f`が[`reference_wrapper`](/reference/functional/reference_wrapper.md)か関数ポインタを保持している場合は、例外を投げるべきではない。`f`が関数オブジェクトを保持している場合は、そのコピーコンストラクタもしくはムーブコンストラクタが[`bad_alloc`](/reference/new/bad_alloc.md)やその他の例外を投げる可能性がある。 +- (3) : + - C++11 + - `f`のターゲットが[`reference_wrapper`](/reference/functional/reference_wrapper.md)経由で渡された呼び出し可能オブジェクト、もしくは関数ポインタである場合は、例外を投げない + - そうでない場合は、[`bad_alloc`](/reference/new/bad_alloc.md)や、格納された呼び出し可能オブジェクトのコピーコンストラクタが投げる例外を送出する可能性がある + - C++17 + - 例外を投げない条件が、`f`のターゲットが[`reference_wrapper`](/reference/functional/reference_wrapper.md)の特殊化、もしくは関数ポインタである場合として規定された +- (4) : + - C++11 + - 例外に関する規定はない + - C++17 + - `f`のターゲットが[`reference_wrapper`](/reference/functional/reference_wrapper.md)の特殊化、もしくは関数ポインタである場合は、例外を投げない + - そうでない場合は、[`bad_alloc`](/reference/new/bad_alloc.md)や、格納された呼び出し可能オブジェクトのコピーコンストラクタ/ムーブコンストラクタが投げる例外を送出する可能性がある + - C++20 + - 保持する対象によらず`noexcept`である +- (8) : + - C++11 : (3)のC++11の規定と同じ +- (10) : + - C++11 + - `f`が関数ポインタ、もしくは`reference_wrapper`である場合は、例外を投げない + - そうでない場合は、[`bad_alloc`](/reference/new/bad_alloc.md)や、`F`のコピーコンストラクタ/ムーブコンストラクタが投げる例外を送出する可能性がある ## 備考 @@ -276,6 +297,16 @@ int main() - [LWG Issue 2132. `std::function` ambiguity](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2132) - C++14から、(5)と(10)でシグニチャが合わない関数オブジェクトが渡された場合に、SFINAEされるようになった。 - [P0302R1 Removing Allocator Support in `std::function` (rev 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r1.html) -- [P0771R1 std::function move constructor should be noexcept](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0771r1.pdf) +- [LWG Issue 2393. `std::function`'s Callable definition is broken](https://cplusplus.github.io/LWG/issue2393) + - C++17で、格納可能な要件が*Lvalue-Callable*(`INVOKE`を左辺値参照として行える型)として整理され、右辺値参照修飾の呼び出し演算子のみを持つ型は格納できないことが明確化された +- [LWG Issue 2565. `std::function`'s move constructor should guarantee nothrow for reference_wrappers and function pointers](https://cplusplus.github.io/LWG/issue2565) + - C++17で、ムーブコンストラクタ(4)も、`reference_wrapper`か関数ポインタを保持する場合は例外を投げないことが規定された(コピーコンストラクタと同様の保証) - [LWG Issue 2774. `std::function` construction vs assignment](https://cplusplus.github.io/LWG/issue2774) - C++23から、`function(F)`のオーバーロードが`function(F&&)`に変更された +- [LWG Issue 2781. Contradictory requirements for `std::function` and `std::reference_wrapper`](https://cplusplus.github.io/LWG/issue2781) + - 例外を投げない対象が「`reference_wrapper`の特殊化」である旨に文言が整理され、矛盾が解消された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。矛盾した文言の修正であり、処理系の挙動は変わらないため +- [P0771R1 std::function move constructor should be noexcept](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0771r1.pdf) +- [LWG Issue 2850. `std::function` move constructor does unnecessary work](https://cplusplus.github.io/LWG/issue2850) + - ムーブコンストラクタの効果が「`*this`のターゲットが構築前の`f`のターゲットと等価になる」旨に緩和され、別途確保されたターゲットの所有権移動による最適化が許容された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元の規定は主要な処理系の実際の動作(ヒープ上のターゲットはポインタを移動するだけ)と矛盾しており、規定を実装に合わせたものであるため diff --git a/reference/functional/function/swap_free.md b/reference/functional/function/swap_free.md index d0c7b9d0b5..4745bc2644 100644 --- a/reference/functional/function/swap_free.md +++ b/reference/functional/function/swap_free.md @@ -7,7 +7,9 @@ ```cpp namespace std { template - void swap(function& x, function& y); + void swap(function& x, function& y); // (1) C++11 + template + void swap(function& x, function& y) noexcept; // (1) C++17 } ``` @@ -66,3 +68,5 @@ int main() ## 参照 +- [LWG Issue 2062. Effect contradictions w/o no-throw guarantee of `std::function` swaps](https://cplusplus.github.io/LWG/issue2062) + - C++17で、メンバ`swap`と一貫させるため、非メンバ`swap`にも`noexcept`が付与された diff --git a/reference/functional/function/target.md b/reference/functional/function/target.md index 5ad1e73077..eebe9ee97a 100644 --- a/reference/functional/function/target.md +++ b/reference/functional/function/target.md @@ -17,12 +17,12 @@ const T* target() const noexcept; 元となる関数を取得する。 -## 要件 -型`T`が、`ArgTypes...`型をパラメータにとり、`R`を戻り値の型とする関数、または関数オブジェクトであること。 +## 戻り値 +[`target_type()`](target_type.md) `== typeid(T)`ならば、保持している関数へのポインタを返す。そうでなければヌルポインタを返す。 -## 戻り値 -[`target_type()`](target_type.md) `== typeid(T)`ならば、保持している関数へのポインタを返す。そうれなければヌルポインタを返す。 +## 備考 +- C++14までは、型`T`が「`ArgTypes...`型をパラメータにとり`R`を戻り値の型とする関数、または関数オブジェクトであること」が要件とされており、それ以外の型を指定した場合の動作は未定義であった。C++17でこの要件は削除され、`T`が呼び出し可能な型であるかどうかによらず、[`target_type()`](target_type.md) `!= typeid(T)`であればヌルポインタを返すことが保証される。 ## 例 @@ -84,3 +84,6 @@ int main() ## 参照 +- [LWG Issue 2591. `std::function`'s member template `target()` should not lead to undefined behaviour](https://cplusplus.github.io/LWG/issue2591) + - `T`が呼び出し可能型であることの事前条件が削除され、`target_type() != typeid(T)`のとき`T`の呼び出し可能性によらずヌルポインタを返す、広い契約の関数となった + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元は事前条件違反として未定義動作だった領域の明文化であり、処理系は当初からヌルポインタを返していたため diff --git a/reference/functional/greater.md b/reference/functional/greater.md index 449188cdd5..0ef18d8c98 100644 --- a/reference/functional/greater.md +++ b/reference/functional/greater.md @@ -69,6 +69,10 @@ namespace std { | `is_transparent` | `operator()` が関数テンプレートである事を示すタグ型。
実装依存の型であるがあくまでタグ型であり、型そのものには意味はない。(`T` が `void` の場合のみ) | C++14 | +## 備考 +- `greater`の`operator()`が組み込みのポインタ比較演算子を呼び出す場合、その比較は厳密な全順序を与える。この順序は、`less`/`greater`/`less_equal`/`greater_equal`の各特殊化の間で一貫しており、かつ組み込みのポインタ比較演算子が定義される場合はその結果とも一致する。 + + ## 例 ```cpp example @@ -93,3 +97,7 @@ true - [N3789 Constexpr Library Additions: functional](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm) - [P0005R4 Adopt `not_fn` from Library Fundamentals 2 for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2450. `(greater|less|greater_equal|less_equal)` do not yield a total order for pointers](https://cplusplus.github.io/LWG/issue2450) + - C++17で、`greater`がポインタを比較する場合に全順序を与えることが規定された(非`void`版と同様) +- [LWG Issue 2562. Consistent total ordering of pointers by comparison functors](https://cplusplus.github.io/LWG/issue2562) + - C++17で、`less`/`greater`/`less_equal`/`greater_equal`が同一ポインタ型に対して同じ全順序を与え、組み込みのポインタ比較演算子とも一致することが規定された diff --git a/reference/functional/greater_equal.md b/reference/functional/greater_equal.md index 1aee31791c..26dc7cef81 100644 --- a/reference/functional/greater_equal.md +++ b/reference/functional/greater_equal.md @@ -69,6 +69,10 @@ namespace std { | `is_transparent` | `operator()` が関数テンプレートである事を示すタグ型。
実装依存の型であるがあくまでタグ型であり、型そのものには意味はない。(`T` が `void` の場合のみ) | C++14 | +## 備考 +- `greater_equal`の`operator()`が組み込みのポインタ比較演算子を呼び出す場合、その比較は厳密な全順序を与える。この順序は、`less`/`greater`/`less_equal`/`greater_equal`の各特殊化の間で一貫しており、かつ組み込みのポインタ比較演算子が定義される場合はその結果とも一致する。 + + ## 例 ```cpp example @@ -93,3 +97,7 @@ true - [N3789 Constexpr Library Additions: functional](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm) - [P0005R4 Adopt `not_fn` from Library Fundamentals 2 for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2450. `(greater|less|greater_equal|less_equal)` do not yield a total order for pointers](https://cplusplus.github.io/LWG/issue2450) + - C++17で、`greater_equal`がポインタを比較する場合に全順序を与えることが規定された(非`void`版と同様) +- [LWG Issue 2562. Consistent total ordering of pointers by comparison functors](https://cplusplus.github.io/LWG/issue2562) + - C++17で、`less`/`greater`/`less_equal`/`greater_equal`が同一ポインタ型に対して同じ全順序を与え、組み込みのポインタ比較演算子とも一致することが規定された diff --git a/reference/functional/hash.md b/reference/functional/hash.md index 041e785e10..e0bebd15a7 100644 --- a/reference/functional/hash.md +++ b/reference/functional/hash.md @@ -67,6 +67,8 @@ namespace std { | 全ての列挙型 | C++14 | | `nullptr_t` | C++17 | +上記に加え、処理系が提供する拡張整数型(`__int128`など)を含むすべての整数型に対しても特殊化が提供される。 + ## メンバ関数 @@ -206,6 +208,8 @@ found : 3 ## 参照 - [ハッシュ関数 - Wikipedia](https://ja.wikipedia.org/wiki/ハッシュ関数) +- [LWG 2119 - Missing hash specializations for extended integer types](https://cplusplus.github.io/LWG/issue2119) + - C++17で、拡張整数型を含むすべての整数型に対して特殊化が提供されることが明確化された - [LWG 2148 - Hashing enums should be supported directly by `std::hash`](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148) - [LWG 2291 - std::hash is vulnerable to collision DoS attack](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2291) - [LWG 2543 - LWG 2148 (hash support for enum types) seems under-specified](https://cplusplus.github.io/LWG/issue2543) diff --git a/reference/functional/invoke.md b/reference/functional/invoke.md index 5561be02d8..f398b6efda 100644 --- a/reference/functional/invoke.md +++ b/reference/functional/invoke.md @@ -138,4 +138,6 @@ int main() ## 参照 - [C++1z INVOKEコンセプトに従った関数呼び出しをするinvoke()関数 - Faith and Brave - C++で遊ぼう](https://faithandbrave.hateblo.jp/entry/2016/09/07/173344) - [N4169 A proposal to add invoke function template (Revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html) +- [LWG Issue 2807. `std::invoke` should use `std::is_nothrow_callable`](https://cplusplus.github.io/LWG/issue2807) + - C++17で、`invoke`に`noexcept(is_nothrow_invocable_v)`の例外指定が追加された - [P1065R2 constexpr INVOKE](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1065r2.html) diff --git a/reference/functional/less.md b/reference/functional/less.md index f611f9c33e..6ac9abd2a5 100644 --- a/reference/functional/less.md +++ b/reference/functional/less.md @@ -69,6 +69,10 @@ namespace std { | `is_transparent` | `operator()` が関数テンプレートである事を示すタグ型。
実装依存の型であるがあくまでタグ型であり、型そのものには意味はない。(`T` が `void` の場合のみ) | C++14 | +## 備考 +- `less`の`operator()`が組み込みのポインタ比較演算子を呼び出す場合、その比較は厳密な全順序を与える。この順序は、`less`/`greater`/`less_equal`/`greater_equal`の各特殊化の間で一貫しており、かつ組み込みのポインタ比較演算子が定義される場合はその結果とも一致する。 + + ## 例 ```cpp example @@ -93,3 +97,7 @@ true - [N3789 Constexpr Library Additions: functional](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm) - [P0005R4 Adopt `not_fn` from Library Fundamentals 2 for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2450. `(greater|less|greater_equal|less_equal)` do not yield a total order for pointers](https://cplusplus.github.io/LWG/issue2450) + - C++17で、`less`がポインタを比較する場合に全順序を与えることが規定された(非`void`版と同様) +- [LWG Issue 2562. Consistent total ordering of pointers by comparison functors](https://cplusplus.github.io/LWG/issue2562) + - C++17で、`less`/`greater`/`less_equal`/`greater_equal`が同一ポインタ型に対して同じ全順序を与え、組み込みのポインタ比較演算子とも一致することが規定された diff --git a/reference/functional/less_equal.md b/reference/functional/less_equal.md index 0393fa9297..4a21894d57 100644 --- a/reference/functional/less_equal.md +++ b/reference/functional/less_equal.md @@ -69,6 +69,10 @@ namespace std { | `is_transparent` | `operator()` が関数テンプレートである事を示すタグ型。
実装依存の型であるがあくまでタグ型であり、型そのものには意味はない。(`T` が `void` の場合のみ) | C++14 | +## 備考 +- `less_equal`の`operator()`が組み込みのポインタ比較演算子を呼び出す場合、その比較は厳密な全順序を与える。この順序は、`less`/`greater`/`less_equal`/`greater_equal`の各特殊化の間で一貫しており、かつ組み込みのポインタ比較演算子が定義される場合はその結果とも一致する。 + + ## 例 ```cpp example @@ -93,3 +97,7 @@ true - [N3789 Constexpr Library Additions: functional](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm) - [P0005R4 Adopt `not_fn` from Library Fundamentals 2 for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2450. `(greater|less|greater_equal|less_equal)` do not yield a total order for pointers](https://cplusplus.github.io/LWG/issue2450) + - C++17で、`less_equal`がポインタを比較する場合に全順序を与えることが規定された(非`void`版と同様) +- [LWG Issue 2562. Consistent total ordering of pointers by comparison functors](https://cplusplus.github.io/LWG/issue2562) + - C++17で、`less`/`greater`/`less_equal`/`greater_equal`が同一ポインタ型に対して同じ全順序を与え、組み込みのポインタ比較演算子とも一致することが規定された diff --git a/reference/functional/mem_fn.md b/reference/functional/mem_fn.md index 7942cc8082..235fda9857 100644 --- a/reference/functional/mem_fn.md +++ b/reference/functional/mem_fn.md @@ -25,11 +25,14 @@ namespace std { ## 戻り値 -### C++17まで +### C++14まで `fn(t, a2, ..., aN)` の呼出しが [`INVOKE`](/reference/concepts/Invoke.md)`(pm, t, a2, ..., aN)` と等価となる [*Callable*](/reference/concepts/Callable.md) オブジェクト `fn` を返す。 `fn` の型には、必要に応じて型の別名 `argument_type`, `first_argument_type`, `second_argument_type`, `result_type` が定義される。 +### C++17から +C++14までと同様だが、`fn`が*simple call wrapper*(引数を完全転送する呼び出しラッパー)であることが要求される。すなわち、右辺値の実引数は右辺値参照として、左辺値の実引数は左辺値参照として、それぞれ`pm`へ渡される。これにより、値渡しのパラメータを持つメンバ関数ポインタに対して余分なコピーやムーブが発生しないことが保証される。 + ### C++20から `fn(call_args...)`の呼び出しが[`invoke`](/reference/functional/invoke.md)`(pmd, call_args...)`を行う*simple call wrapper*オブジェクト `fn` を返す。 ここで、`pmd`は`R T::* pmd(pm)`のように初期化された`fn`が保持するメンバポインタ、`call_args...`は`pm`の関数呼び出しに必要となる引数リストである。 @@ -92,5 +95,8 @@ true ## 参照 - [LWG Issue 2048. Unnecessary `mem_fn` overloads](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2048) - 不必要なオーバーロードを、C++14で削除 +- [LWG Issue 2486. `mem_fn()` should be required to use perfect forwarding](https://cplusplus.github.io/LWG/issue2486) + - `mem_fn`が返すオブジェクトが引数を完全転送する*simple call wrapper*であることが要求された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。引数の転送方法は元の規定では未規定であり、処理系は当初から完全転送していたため - [LWG Issue 2489. mem_fn() should be noexcept](https://wg21.cmeerw.net/lwg/issue2489) - [P1065R2 constexpr INVOKE](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1065r2.html) diff --git a/reference/future/async.md b/reference/future/async.md index 45152d4f86..965109f822 100644 --- a/reference/future/async.md +++ b/reference/future/async.md @@ -87,6 +87,8 @@ namespace std { - [`resource_unavailable_try_again`](/reference/system_error/errc.md) : [`launch::async`](launch.md)が指定され、新たなスレッドを起動しようとしたができなかった +また、内部データ構造のメモリ確保に失敗した場合、[`std::bad_alloc`](/reference/new/bad_alloc.md)が投げられる可能性がある。 + ## launch::asyncポリシーを指定した場合の注意点 ### 戻り値 @@ -195,9 +197,9 @@ foo() = 3 ## 参照 -- [LWG Issue 2120. What should `async` do if neither `async` nor `deferred` is set in policy?](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2120) - [LWG Issue 2021. Further incorrect usages of `result_of`](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2021) - C++14で、戻り値型の計算に`decay`を適用するようにした。 +- [LWG Issue 2120. What should `async` do if neither `async` nor `deferred` is set in policy?](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2120) - [async関数launch::asyncポリシーとfutureのちょっと特殊な動作 - yohhoyの日記](https://yohhoy.hatenadiary.jp/entry/20120317/p1) - [P0604R0 Resolving GB 55, US 84, US 85, US 86](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html) - [P0600R1 `[[nodiscard]]` in the Library, Rev1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0600r1.pdf) @@ -206,5 +208,8 @@ foo() = 3 - [<future> functions - Microsoft Docs](https://docs.microsoft.com/en-us/cpp/standard-library/future-functions?view=vs-2019#remarks) - [P2422R1 Remove `nodiscard` annotations from the standard library specification](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2422r1.html) - C++26で`[[nodiscard]]`指定が削除された +- [LWG Issue 2752. Throws: clauses of `async` and `packaged_task` are unimplementable](https://cplusplus.github.io/LWG/issue2752) + - 実装上必要な内部確保を反映し、`async`が[`bad_alloc`](/reference/new/bad_alloc.md)も送出しうることが規定された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。型消去のための内部確保が必要なため元のThrows節は実装不可能であり、処理系は当初から`bad_alloc`を送出しえたため - [LWG Issue 3476. `thread` and `jthread` constructors require that the parameters be move-constructible](https://cplusplus.github.io/LWG/issue3476) - C++23で、`is_constructible`要件が既に目的を満たすため、冗長だったムーブ構築可能(`is_move_constructible`)の要件が削除された diff --git a/reference/future/future/get.md b/reference/future/future/get.md index e4a0414307..e7883e51a2 100644 --- a/reference/future/future/get.md +++ b/reference/future/future/get.md @@ -216,3 +216,6 @@ int main() ## 参照 - [LWG Issue 2096. Incorrect constraints of `future::get` in regard to `MoveAssignable`](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2096) - C++14から、`future::get()`の戻り値が変更された。C++11では「ムーブ代入可能ならムーブで返し、そうでなければコピーで返す」となっていたが、これは現実的ではない制約だった。 +- [LWG Issue 2531. `future::get` should explicitly state that the shared state is released](https://cplusplus.github.io/LWG/issue2531) + - `get()`が共有状態を解放することが効果として明記された(`valid() == false`となる旨は事後条件に既出) + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。既存の事後条件から導かれる内容の明文化であり、挙動は変わらないため diff --git a/reference/future/future/share.md b/reference/future/future/share.md index 41cbed53c3..c5070ef19c 100644 --- a/reference/future/future/share.md +++ b/reference/future/future/share.md @@ -6,7 +6,8 @@ * cpp11[meta cpp] ```cpp -shared_future share(); +shared_future share(); // (1) C++11 +shared_future share() noexcept; // (1) C++17 ``` * shared_future[link ../shared_future.md] @@ -26,6 +27,11 @@ shared_future share(); [`shared_future`](../shared_future.md)`(std::`[`move`](/reference/utility/move.md)`(*this))` +## 例外 +- 投げない +- C++17以降は`noexcept`指定されている。[`valid()`](valid.md) `== false`である`future`に対して呼び出してもよく(広い契約)、その場合は無効な状態の[`shared_future`](../shared_future.md)が返る + + ## 例 ```cpp example #include @@ -91,3 +97,5 @@ int main() [futureとshared_future - yohhoyの日記](http://d.hatena.ne.jp/yohhoy/20120201/p1) [future::share()は何のためにあるのか - Faith and Brave - C++で遊ぼう](http://d.hatena.ne.jp/faith_and_brave/20121029/1351494001) +- [LWG Issue 2556. Wide contract for `future::share()`](https://cplusplus.github.io/LWG/issue2556) + - C++17で、`share()`が広い契約(`valid()`が`false`でも呼び出し可)を持ち例外を投げないことを反映して`noexcept`が付与された diff --git a/reference/future/packaged_task.md b/reference/future/packaged_task.md index 42d13de2b6..7ca367acaf 100644 --- a/reference/future/packaged_task.md +++ b/reference/future/packaged_task.md @@ -69,7 +69,7 @@ namespace std { | 名前 | 説明 | 対応バージョン | |------|------|----------------| -| [`uses_allocator`](packaged_task/uses_allocator.md) | `packaged_task`による特殊化 | C++11 | +| [`uses_allocator`](packaged_task/uses_allocator.md) | `packaged_task`による特殊化 | C++11
C++20で削除 | ## 例 diff --git a/reference/future/packaged_task/op_constructor.md b/reference/future/packaged_task/op_constructor.md index 5acbc814e6..2d99eee502 100644 --- a/reference/future/packaged_task/op_constructor.md +++ b/reference/future/packaged_task/op_constructor.md @@ -118,10 +118,12 @@ int main() ## 参照 - [LWG Issue 2067. `packaged_task` should have deleted copy c'tor with const parameter](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2067) - [LWG Issue 2097. `packaged_task` constructors should be constrained](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2097) +- [LWG Issue 2752. Throws: clauses of `async` and `packaged_task` are unimplementable](https://cplusplus.github.io/LWG/issue2752) + - C++17で、アロケータを取る版において、アロケータの`allocate`から送出される例外も例外指定に加えられた(`f`のコピー/ムーブ構築や`bad_alloc`はC++14で既に規定済み)。なおアロケータを取る版自体はLWG 2976 (C++20)で削除された - [LWG Issue 2921. `packaged_task` and type-erased allocators](https://wg21.cmeerw.net/lwg/issue2921) - [`std::function`のコンストラクタ](/reference/functional/function/op_constructor.md)と同様の理由により、アロケータを受け取るコンストラクタを削除 -- [LWG Issue 3039. Unnecessary `decay` in `thread` and `packaged_task`](https://wg21.cmeerw.net/lwg/issue3039) - [P3503R3 Make type-erased allocator use in `promise` and `packaged_task` consistent](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3503r3.html) - C++26でアロケータを受け取るコンストラクタを再追加 +- [LWG Issue 3039. Unnecessary `decay` in `thread` and `packaged_task`](https://wg21.cmeerw.net/lwg/issue3039) - [LWG Issue 4154. The Mandates for `std::packaged_task`'s constructor from a callable entity should consider decaying](https://cplusplus.github.io/LWG/issue4154) - C++26で、適格要件が`is_invocable_r_v`から`is_invocable_r_v&, ArgTypes...>`に修正された(`F`をdecayした型で判定する) diff --git a/reference/future/packaged_task/uses_allocator.md b/reference/future/packaged_task/uses_allocator.md index 1bb8c538e8..b05fd1d714 100644 --- a/reference/future/packaged_task/uses_allocator.md +++ b/reference/future/packaged_task/uses_allocator.md @@ -3,6 +3,7 @@ * std[meta namespace] * class template[meta id-type] * cpp11[meta cpp] +* cpp20removed[meta cpp] ```cpp namespace std { @@ -13,6 +14,9 @@ namespace std { ``` * true_type[link /reference/type_traits/true_type.md] +[`packaged_task`](../packaged_task.md)のアロケータサポートはC++17で削除されたが、この特殊化はC++17の規格には残っていた。C++20で、取り残されていたこの特殊化も削除された。 + + ## 概要 `uses_allocator`の、`packaged_task`に対する特殊化。 @@ -37,3 +41,5 @@ namespace std { ## 参照 +- [LWG Issue 2976. Dangling `uses_allocator` specialization for `packaged_task`](https://cplusplus.github.io/LWG/issue2976) + - `packaged_task`のアロケータサポート削除に伴い残っていたこの特殊化が削除された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/future/promise/set_exception.md b/reference/future/promise/set_exception.md index 60177d251a..90192741fb 100644 --- a/reference/future/promise/set_exception.md +++ b/reference/future/promise/set_exception.md @@ -14,6 +14,10 @@ void set_exception(exception_ptr p); 結果の例外を設定する +## 事前条件 +`p`はヌルでないこと。 + + ## 効果 例外ポインタ`p`をアトミックに共有状態に格納し、準備完了状態([`future_status::ready`](../future_status.md))にする。 @@ -93,3 +97,5 @@ invalid argument! ## 参照 +- [LWG Issue 2276. Missing requirement on `std::promise::set_exception`](https://cplusplus.github.io/LWG/issue2276) + - C++17で、引数`p`がヌルでないことが事前条件として規定された diff --git a/reference/future/promise/set_exception_at_thread_exit.md b/reference/future/promise/set_exception_at_thread_exit.md index aff1274977..16c026ef3e 100644 --- a/reference/future/promise/set_exception_at_thread_exit.md +++ b/reference/future/promise/set_exception_at_thread_exit.md @@ -14,6 +14,10 @@ void set_exception_at_thread_exit(exception_ptr p); スレッド終了時に結果の例外を設定する +## 事前条件 +`p`はヌルでないこと。 + + ## 効果 例外ポインタ`p`を、すぐに準備完了状態([`future_status::ready`](../future_status.md))にはせずに共有状態に格納する。現在のスレッドが終了し、スレッドローカル記憶域を持つ全てのオブジェクトを破棄したあと、準備完了状態にする。 @@ -99,3 +103,5 @@ invalid argument! ## 参照 - [_at_thread_exit系の関数が存在している理由](/article/lib/at_thread_exit.md) +- [LWG Issue 2276. Missing requirement on `std::promise::set_exception`](https://cplusplus.github.io/LWG/issue2276) + - C++17で、引数`p`がヌルでないことが事前条件として規定された diff --git a/reference/ios/ios_base/failure.md b/reference/ios/ios_base/failure.md index cfd4fbd2f9..4c18841b85 100644 --- a/reference/ios/ios_base/failure.md +++ b/reference/ios/ios_base/failure.md @@ -54,6 +54,8 @@ C++11 からは、エラー内容としてメッセージだけではなく、[` このため、C++03 でも [`exception`](../../exception/exception.md) から直接派生していないかもしれないので、注意。 (当然 C++11 でも [`system_error`](../../system_error/system_error.md) を直接継承していない可能性がある) - C++03 まではデストラクタが宣言されていたが、例外指定が誤っていたため(基底クラス [`exception`](../../exception/exception.md) のデストラクタには `throw()` が付いているため、派生クラスにも `throw()` が必要)、C++11 では宣言自体が削除された。 +- C++17 からは、[`ios_base`](../ios_base.md)`::failure` を、クラスとして定義するのではなく、[`system_error`](../../system_error/system_error.md) から派生したクラスへの別名(シノニム)として定義してもよいことになっている。これは、規格バージョン間でABIの互換性を保つ柔軟性を処理系に与えるためである。 + このため、`class std::ios_base::failure` のような elaborated-type-specifier が使用できるとは限らない。 ## バージョン @@ -82,6 +84,8 @@ C++11 からは、エラー内容としてメッセージだけではなく、[` - [`iostream_category`](../iostream_category.md) - [N2769 Detailed Reporting for Input/Output Library Errors (Revision 2)](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2769.htm) 基底クラスの変更を含む C++11 での提案文書 +- [LWG Issue 2462. `std::ios_base::failure` is overspecified](https://cplusplus.github.io/LWG/issue2462) + C++17で、`ios_base::failure`を[`system_error`](../../system_error/system_error.md)から派生したクラスへのシノニム(typedef 等)として定義してよいことが規定された(ABI の柔軟性のため。上記 GCC の `_GLIBCXX_USE_CXX11_ABI` の事情もこれに関係する) - [DR331 bad declaration of destructor for ios_base::failure](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#331) デストラクタ宣言削除の Defect Report - [Bug 66145 - [5/6 Regression] std::ios_base::failure objects thrown from libstdc++.so use old ABI](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145) diff --git a/reference/istream/basic_istream/op_istream_free.md b/reference/istream/basic_istream/op_istream_free.md index 517747048f..6de6e41c68 100644 --- a/reference/istream/basic_istream/op_istream_free.md +++ b/reference/istream/basic_istream/op_istream_free.md @@ -30,6 +30,8 @@ namespace std { // 右辺値参照ストリームからの入力 template basic_istream& operator>>(basic_istream&& is, T& x); // (7) C++11 + template + basic_istream& operator>>(basic_istream&& is, T&& x); // (7) C++17 } ``` @@ -49,6 +51,11 @@ namespace std { あるいは、これらの代わりに`basic_string` (`std::string`、`std::wstring`など)に対して`>>`演算子を使用することでも、この危険を回避できる。 参考: [`>>`演算子 (`basic_string`)](../../string/basic_string/op_istream.md)。 +## テンプレートパラメータ制約 +- (7) : + - C++17 : 式`is >> `[`std::forward`](/reference/utility/forward.md)`(x)`が適格であること + + ## 効果 ### 文字 @@ -81,9 +88,13 @@ namespace std { `width()`の値を変更するには、`setw`マニピュレータまたは`width()`メンバ関数を使用する。 -### 右辺値参照ストリームからの入力 (C++11) +### 右辺値参照ストリームからの入力 + +このオーバーロードは、ストリームの一時オブジェクトなどに対して`>>`演算子を利用可能にするためのものである。 -`is >> x`を実行する。このオーバーロードは、ストリームの一時オブジェクトなどに対して`>>`演算子を利用可能にするためのものである。 +- C++11 : `is >> x`を実行する +- C++17 : `is >> `[`std::forward`](/reference/utility/forward.md)`(x)`を実行する + - 実引数`x`を`T&&`(転送参照)で受け取って完全転送するため、`&arr[0]`のような右辺値の被入力対象も扱えるようになった ## 戻り値 @@ -132,6 +143,10 @@ TBD - [`basic_streambuf`](../../streambuf/basic_streambuf.md) ## 参照 +- [LWG Issue 2328. Rvalue stream extraction should use perfect forwarding](https://cplusplus.github.io/LWG/issue2328) + - C++17で、右辺値参照ストリーム版(7)が被入力対象を`T&&`(転送参照)で受け取り完全転送するよう変更された - [P0487R1 Fixing `operator>>(basic_istream&, CharT*)` (LWG 2499)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0487r1.html) +- [LWG Issue 2534. Constrain rvalue stream operators](https://cplusplus.github.io/LWG/issue2534) + - C++17で、右辺値ストリーム版`operator>>`が`is >> x`が妥当な場合のみオーバーロード解決に参加するよう制約化され、SFINAEでのストリーム可否判定が正しく機能するようになった - [P1264R2 Revising the wording of stream input operations](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1264r2.pdf) - C++23でローカルエラー状態の概念が導入され、入力関数のエラー処理セマンティクスが明確化された diff --git a/reference/istream/basic_istream/seekg.md b/reference/istream/basic_istream/seekg.md index cc1227adf7..3db56ceea7 100644 --- a/reference/istream/basic_istream/seekg.md +++ b/reference/istream/basic_istream/seekg.md @@ -19,7 +19,7 @@ basic_istream& seekg(off_type off, seekdir dir); ## 効果 -1. (`pos_type`を引数に取るもののみ)初めにeofbitを消去する。 +1. 初めにeofbitを消去する。 1. `sentry`オブジェクトを構築する。`sentry`オブジェクトが失敗を示した場合、何もしない。 1. 与えられた実引数により、以下のいずれかを実行する。 - `rdbuf()->pubseekpos(pos, ios_base::in)` @@ -84,6 +84,7 @@ basic_istream& seekg(pos_type pos) { basic_istream& seekg(off_type off, seekdir dir) { iostate state = goodbit; try { + this->clear(this->rdstate() & ~eofbit); sentry s(*this, true); if (s) { if (this->rdbuf()->pubseekoff(off, dir, ios_base::in) == -1) { @@ -126,3 +127,6 @@ basic_istream& seekg(off_type off, seekdir dir) { - [`basic_streambuf::seekoff`](../../streambuf/basic_streambuf/seekoff.md) - [P1264R2 Revising the wording of stream input operations](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1264r2.pdf) - C++23でローカルエラー状態の概念が導入され、入力関数のエラー処理セマンティクスが明確化された +- [LWG Issue 2244. Issue on `basic_istream::seekg`](https://cplusplus.github.io/LWG/issue2244) + - `(off_type, seekdir)`版でも初めにeofbitを消去することが規定された + - この修正は欠陥報告(DR)であり、C++11に遡及して適用される。LWG 1445の解決を適用する際に`(pos_type)`版にのみ文言が入り`(off_type, seekdir)`版への適用が漏れた編集上の誤りの修正であり、処理系は当初から両オーバーロードでeofbitを消去していたため diff --git a/reference/iterator/istream_iterator.md b/reference/iterator/istream_iterator.md index 32463f1eed..2b1765915e 100644 --- a/reference/iterator/istream_iterator.md +++ b/reference/iterator/istream_iterator.md @@ -22,6 +22,10 @@ namespace std { ストリームからの読み取りが`fail() == true`となる場合に、イテレータは`end`イテレータと等しくなる。 +## 要件 +- 型`T`が、デフォルト構築可能(*Cpp17DefaultConstructible*)、コピー構築可能(*Cpp17CopyConstructible*)、かつコピー代入可能(*Cpp17CopyAssignable*)の要件を満たすこと。 + + ## メンバ関数 | 名前 | 説明 | 対応バージョン | @@ -98,4 +102,7 @@ int main() ## 関連項目 - [`basic_istream_view`](/reference/ranges/basic_istream_view.md): ストリームからデータを読み込むRange -### 参照 +## 参照 +- [LWG Issue 2878. Missing `DefaultConstructible` requirement for `istream_iterator` default constructor](https://cplusplus.github.io/LWG/issue2878) + - 型`T`が`DefaultConstructible`・`CopyConstructible`・`CopyAssignable`の要件を満たす必要があることが明記された + - この修正は欠陥報告(DR)であり、C++98に遡及して適用される。メンバとして`T`のオブジェクトを保持する以上これらは実装上当初から必須だった要件であり、規定から抜け落ちていたものの明文化であるため diff --git a/reference/iterator/istream_iterator/op_constructor.md b/reference/iterator/istream_iterator/op_constructor.md index 80f9d58fc6..faa5e29acc 100644 --- a/reference/iterator/istream_iterator/op_constructor.md +++ b/reference/iterator/istream_iterator/op_constructor.md @@ -68,5 +68,8 @@ int main() ## 参照 - [LWG Issue 2576. `istream_iterator` and `ostream_iterator` should use `std::addressof`](https://wg21.cmeerw.net/lwg/issue2576) +- [LWG Issue 2804. Unconditional `constexpr` default constructor for `istream_iterator`](https://cplusplus.github.io/LWG/issue2804) + - デフォルトコンストラクタ(1)の宣言に書かれていた`see below`というプレースホルダが`constexpr`と綴り直された(`T`がトリビアルにデフォルト構築可能な場合に`constexpr`コンストラクタとなるという条件は、C++17時点でも効果として残っている) + - この修正は欠陥報告(DR)であり、C++11に遡及して適用される。宣言の書き方を直す編集上の修正であり、処理系は当初から`constexpr`と宣言していたため - [LWG Issue 3600. Making `istream_iterator` copy constructor trivial is an ABI break](https://cplusplus.github.io/LWG/issue3600) - C++23で、コピーコンストラクタが`= default`から明示的に定義された非トリビアルなコンストラクタ(`constexpr`・`noexcept`指定付き)に変更された。既存実装とのABI互換性を保つため、トリビアル化が見送られた diff --git a/reference/iterator/istreambuf_iterator.md b/reference/iterator/istreambuf_iterator.md index 6843e94b8b..da281ecf11 100644 --- a/reference/iterator/istreambuf_iterator.md +++ b/reference/iterator/istreambuf_iterator.md @@ -30,7 +30,7 @@ namespace std { | [`(constructor)`](istreambuf_iterator/op_constructor.md) | コンストラクタ | | | `~istreambuf_iterator() = default` | デストラクタ | | | [`operator*`](istreambuf_iterator/op_deref.md) | 間接参照 | | -| [`operator->`](istreambuf_iterator/op_arrow.md) | メンバアクセス | C++11 | +| [`operator->`](istreambuf_iterator/op_arrow.md) | メンバアクセス | C++11
C++17で削除 | | [`operator++`](istreambuf_iterator/op_increment.md) | イテレータをインクリメントする | | | [`equal`](istreambuf_iterator/equal.md) | `istreambuf_iterator`オブジェクトの等値比較 | | diff --git a/reference/iterator/istreambuf_iterator/op_arrow.md b/reference/iterator/istreambuf_iterator/op_arrow.md index b79c963510..042cae914a 100644 --- a/reference/iterator/istreambuf_iterator/op_arrow.md +++ b/reference/iterator/istreambuf_iterator/op_arrow.md @@ -4,11 +4,15 @@ * istreambuf_iterator[meta class] * function[meta id-type] * cpp11[meta cpp] +* cpp17removed[meta cpp] ```cpp pointer operator->() const; ``` +このメンバ関数は、C++11で追加されたが仕様が定まらないまま各処理系で挙動が分かれていたため、C++17で削除された。 + + ## 概要 イテレータを介してメンバアクセスする @@ -41,3 +45,6 @@ pointer operator->() const; ## 参照 +- [LWG Issue 2790. Missing specification of `istreambuf_iterator::operator->`](https://cplusplus.github.io/LWG/issue2790) + - C++17で、仕様が定まらないこのメンバ関数が削除された + - このメンバ関数には効果の規定が存在せず、主要な処理系も提供していなかったため、削除による実際の影響はほとんどない diff --git a/reference/iterator/istreambuf_iterator/op_constructor.md b/reference/iterator/istreambuf_iterator/op_constructor.md index 3e9523557b..9efaf19c69 100644 --- a/reference/iterator/istreambuf_iterator/op_constructor.md +++ b/reference/iterator/istreambuf_iterator/op_constructor.md @@ -27,7 +27,7 @@ istreambuf_iterator(const proxy& p) noexcept; // (6) C++11 - (2) : [`default_sentinel`](/reference/iterator/default_sentinel_t.md)を受け取り、(1)と同等の構築をより明示的に行う。 - (3) : コピーコンストラクタ。 - (4) : `s.rdbuf()`をメンバ変数として保持する。 -- (5) : `s`をメンバ変数として保持する。 +- (5) : `s`をメンバ変数として保持する。`s`がヌルポインタである場合、終端イテレータが構築される。 - (6) : 後置`operator++()`が返すであろうproxyオブジェクトを受け取り、そのオブジェクトが指す`streambuf`オブジェクトへのポインタをメンバ変数として保持する。 @@ -61,3 +61,6 @@ int main() ``` ## 参照 +- [LWG Issue 2544. `istreambuf_iterator(basic_streambuf* s)` effects unclear when `s` is `0`](https://cplusplus.github.io/LWG/issue2544) + - (5)に`s`がヌルポインタの場合は終端イテレータが構築されることが明確化された + - この修正は欠陥報告(DR)であり、C++98に遡及して適用される。クラスの導入部で既に規定されていた内容を各コンストラクタの効果として明記しただけであり、処理系の挙動は変わらないため diff --git a/reference/list/list/sort.md b/reference/list/list/sort.md index e1f97b98a4..e3ec90deb9 100644 --- a/reference/list/list/sort.md +++ b/reference/list/list/sort.md @@ -23,10 +23,11 @@ constexpr void sort(Compare comp); // (2) C++26 ## 効果 -型`T`の`operator<`もしくは`comp`に基いてコンテナの要素を並べ替える。 - -この操作は安定である。同値要素の順序は保持される。 -この操作は、イテレータと参照の有効性に影響しない。 +型`T`の`operator<`もしくは`comp`に基いてコンテナの要素を並べ替える。 + +- 例外が送出された場合、`*this`の要素の順序は未規定となる。 +- この操作は安定である。同値要素の順序は保持される。 +- この操作は、イテレータと参照の有効性に影響しない。 ## 戻り値 @@ -64,4 +65,7 @@ int main() ## 参照 +- [LWG Issue 2824. `list::sort` should say that the order of elements is unspecified if an exception is thrown](https://cplusplus.github.io/LWG/issue2824) + - 比較中に例外が送出された場合は`*this`の要素の順序が未規定となることが明記された([`forward_list::sort`](/reference/forward_list/forward_list/sort.md)と同様) + - この修正は欠陥報告(DR)であり、C++98以降に遡及して適用される。この文言はもともと存在したが編集上の変更で失われたものであり、元の規定でも例外送出時の順序は保証されていなかったため - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/locale/locale/name.md b/reference/locale/locale/name.md index a97da9ca7e..472b1e627f 100644 --- a/reference/locale/locale/name.md +++ b/reference/locale/locale/name.md @@ -52,3 +52,9 @@ C ## 関連項目 - [`locale::classic`](classic.md) - [`locale::global`](global.md) + + +## 参照 +- [LWG Issue 2394. `locale::name` specification unclear — what is implementation-defined?](https://cplusplus.github.io/LWG/issue2394) + - 「名前を持つ場合`locale(name().c_str())`は`*this`と等価である」「文字列の内容の詳細はそれ以外は処理系定義」という文言が削除され、戻り値は「名前があればその名前、なければ`"*"`」のみの規定となった + - この修正は欠陥報告(DR)であり、C++98に遡及して適用される。戻り値は最初の一文で既に完全に規定されており、何が処理系定義なのか不明瞭だった冗長な記述の削除であって、処理系の挙動は変わらないため diff --git a/reference/locale/num_get.md b/reference/locale/num_get.md index 99c31919ac..a686263934 100644 --- a/reference/locale/num_get.md +++ b/reference/locale/num_get.md @@ -13,41 +13,94 @@ namespace std { * locale::facet[link /reference/locale/locale/facet.md] ## 概要 -(ここに、クラスの概要を記載する) +`num_get`は、入力ストリームから数値・真偽値・ポインタを読み取り、解析するためのロケールファセットである。[`basic_istream`](/reference/istream/basic_istream.md)の数値入力演算子[`operator>>`](/reference/istream/basic_istream/op_istream.md)は、このファセットを介して入力の解析を行う。 -### publicメンバ関数 +テンプレートパラメータ`InputIterator`は、入力に使用するイテレータの型を表し、既定では[`istreambuf_iterator`](/reference/iterator/istreambuf_iterator.md)``である。 -| 名前 | 説明 | -|----------------------------|-----------------------| -| `(constructor)` | コンストラクタ | -| `get` | 数値の解析 | +解析処理は`protected`な仮想関数[`do_get`](num_get/do_get.md)に実装されており、`public`メンバ関数[`get`](num_get/get.md)から呼び出される。このクラスを継承して[`do_get`](num_get/do_get.md)をオーバーライドすることで、数値の解析方法をカスタマイズできる。 + + +## メンバ関数 + +| 名前 | 説明 | 対応バージョン | +|-------------------------------------------|----------------|---| +| [`(constructor)`](num_get/op_constructor.md) | コンストラクタ | | +| [`get`](num_get/get.md) | 数値の解析 | | ### 静的メンバ変数 -| 名前 | 説明 | -|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--| -| `static` [`locale::id`](/reference/locale/locale/id.md) `id;` | | +| 名前 | 説明 | 対応バージョン | +|--------------------------------------------------------------|--------------------------------|---| +| `static` [`locale::id`](/reference/locale/locale/id.md) `id;` | このファセットを識別するためのID | | ### protectedメンバ関数 -| 名前 | 説明 | -|---------------------------|--------------------| -| `(destructor)` | デストラクタ | -| `do_get` | 数値の解析 | +| 名前 | 説明 | 対応バージョン | +|---------------------------------------------|--------------|---| +| [`(destructor)`](num_get/op_destructor.md) | デストラクタ | | +| [`do_get`](num_get/do_get.md) | 数値の解析 (virtual) | | -### メンバ型 +## メンバ型 -| 名前 | 説明 | -|------------------------|--------------------------------------------------------| -| `char_type` | 文字型 `charT` | -| `iter_type` | 入力のイテレータ型 `InputIterator` | +| 名前 | 説明 | 対応バージョン | +|-------------|------------------------------------|---| +| `char_type` | 文字型 `charT` | | +| `iter_type` | 入力のイテレータ型 `InputIterator` | | -### 例 -```cpp + +## 例 +```cpp example +#include +#include +#include +#include + +int main() +{ + std::istringstream iss{"42 3.14"}; + + // ストリームのロケールからnum_getファセットを取得する + const auto& facet = std::use_facet>(iss.getloc()); + + std::istreambuf_iterator begin{iss}, end{}; + std::ios_base::iostate err = std::ios_base::goodbit; + + long i = 0; + begin = facet.get(begin, end, iss, err, i); + + // 空白文字は解析されないため、読み飛ばす + ++begin; + + double d = 0.0; + facet.get(begin, end, iss, err, d); + + std::cout << i << std::endl; + std::cout << d << std::endl; +} ``` +* std::num_get[color ff0000] +* std::use_facet[link /reference/locale/use_facet.md] +* facet.get[link num_get/get.md] +* iss.getloc()[link /reference/ios/ios_base/getloc.md] +* std::istreambuf_iterator[link /reference/iterator/istreambuf_iterator.md] +* std::ios_base::iostate[link /reference/ios/ios_base/type-iostate.md] +* std::ios_base::goodbit[link /reference/ios/ios_base/type-iostate.md] ### 出力 ``` +42 +3.14 ``` -### 参照 + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`num_put`](num_put.md) +- [`numpunct`](numpunct.md) +- [`locale`](locale.md) +- [`use_facet`](use_facet.md) +- [`basic_istream`の`operator>>`](/reference/istream/basic_istream/op_istream.md) diff --git a/reference/locale/num_get/do_get.md b/reference/locale/num_get/do_get.md new file mode 100644 index 0000000000..04c4bcdaf7 --- /dev/null +++ b/reference/locale/num_get/do_get.md @@ -0,0 +1,117 @@ +# do_get +* locale[meta header] +* std[meta namespace] +* num_get[meta class] +* function[meta id-type] + +```cpp +protected: + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, bool& val) const; // (1) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long& val) const; // (2) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long long& val) const; // (3) C++11 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned short& val) const; // (4) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned int& val) const; // (5) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned long& val) const; // (6) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned long long& val) const; // (7) C++11 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, float& val) const; // (8) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, double& val) const; // (9) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long double& val) const; // (10) C++98 + virtual iter_type do_get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, void*& val) const; // (11) C++98 +``` +* ios_base[link /reference/ios/ios_base.md] +* ios_base::iostate[link /reference/ios/ios_base/type-iostate.md] + +## 概要 +入力イテレータ範囲`[in, end)`から文字列を読み取り、`val`の型に応じた数値・真偽値・ポインタへ変換する。[`get()`](get.md)から呼び出される、実際の解析を行う仮想関数である。 + +- (1) : `bool`へ変換する +- (2), (3) : 符号付き整数型 (`long`, `long long`) へ変換する +- (4), (5), (6), (7) : 符号なし整数型 (`unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`) へ変換する +- (8), (9), (10) : 浮動小数点数型 (`float`, `double`, `long double`) へ変換する +- (11) : ポインタ (`void*`) へ変換する + + +## 効果 +(2)〜(11)は、入力を数値へ変換する。変換は以下の3段階(Stage 1〜3)で行われる。(1)の`bool`版は、これらとは別に後述の規則で処理される。 + +### Stage 1 : 変換指定の決定 +`str.`[`flags()`](/reference/ios/ios_base/flags.md)から`basefield`・`uppercase`・`boolalpha`を取り出し、変換指定(および必要な長さ修飾子)を決定する。 + +- (2), (3), (4), (5), (6), (7) : 以下の表の条件を上から順に評価し、最初に真となった行の変換指定を使用する + + | 状態 | `stdio`の変換指定に相当 | + |------|-------------------------| + | `basefield == `[`ios_base::oct`](/reference/ios/ios_base/type-fmtflags.md) | `%o` | + | `basefield == `[`ios_base::hex`](/reference/ios/ios_base/type-fmtflags.md) | `%X` | + | `basefield == 0` | `%i` | + | 符号付き整数型 | `%d` | + | 符号なし整数型 | `%u` | + +- (8), (9), (10) : `%g` +- (11) : `%p` + +### Stage 2 : 文字の抽出 +`[in, end)`から、変換指定に合致する文字を順次抽出する。`str.`[`getloc()`](/reference/ios/ios_base/getloc.md)から取得した[`numpunct`](/reference/locale/numpunct.md)ファセットにより、[`numpunct::grouping()`](/reference/locale/numpunct/grouping.md.nolink)が空でない場合は桁区切り文字([`numpunct::thousands_sep()`](/reference/locale/numpunct/thousands_sep.md.nolink))を取り除き、小数点文字([`numpunct::decimal_point()`](/reference/locale/numpunct/decimal_point.md.nolink))は`'.'`に置き換える。 + +### Stage 3 : 数値への変換と格納 +Stage 2で蓄積した文字列(フィールド)を、[``](/reference/cstdlib.md)で宣言される以下の関数の規則に従って数値へ変換する。 + +| オーバーロード | 対象の型 | 変換規則 | +|----------------|----------|----------| +| (2), (3) | 符号付き整数型 | [`std::strtoll`](/reference/cstdlib/strtoll.md.nolink) | +| (4), (5), (6), (7) | 符号なし整数型 | [`std::strtoull`](/reference/cstdlib/strtoull.md.nolink) | +| (8) | `float` | [`std::strtof`](/reference/cstdlib/strtof.md.nolink) | +| (9) | `double` | [`std::strtod`](/reference/cstdlib/strtod.md.nolink) | +| (10) | `long double` | [`std::strtold`](/reference/cstdlib/strtold.md.nolink) | +| (11) | `void*` | 規定されていない | + +格納される値は以下のいずれかであり、いずれの場合も結果は`val`へ格納される。 + +- (2)〜(11) : 変換関数がフィールド全体を変換しなかった場合、`0` +- (2), (3) : `val`に表現できないほど大きな正(負)の値を表す場合、表現可能な最大(最小)の値 +- (4), (5), (6), (7) : `val`に表現できない値を表す場合、表現可能な最大の値 +- (2)〜(11) : それ以外の場合、変換された値 + +変換関数がフィールド全体を変換しなかった場合、または表現可能な範囲外の値を表す場合、`err`に[`std::ios_base::failbit`](/reference/ios/ios_base/type-iostate.md)が設定される。 + +### 桁区切りの検査 +(2)〜(10)では、取り除いた桁区切り文字の位置が[`numpunct::grouping()`](/reference/locale/numpunct/grouping.md.nolink)と整合しているかが検査される。整合していない場合、`err`に[`std::ios_base::failbit`](/reference/ios/ios_base/type-iostate.md)が設定される。 + +### 入力終端の扱い +いずれの場合も、Stage 2の処理が`in == end`の判定によって終了した場合は、`err |= `[`std::ios_base::eofbit`](/reference/ios/ios_base/type-iostate.md)が行われる。 + +### (1) `bool`版の処理 +- `(str.`[`flags()`](/reference/ios/ios_base/flags.md)` & `[`std::ios_base::boolalpha`](/reference/ios/ios_base/type-fmtflags.md)`) == 0`の場合 : `long`と同様に入力を読み取り、格納しようとする値が`0`なら`false`、`1`なら`true`を格納する。それ以外の場合は`true`を格納し、`err`に[`std::ios_base::failbit`](/reference/ios/ios_base/type-iostate.md)を設定する +- そうでない場合 : [`numpunct::truename()`](/reference/locale/numpunct/truename.md.nolink)と[`numpunct::falsename()`](/reference/locale/numpunct/falsename.md.nolink)を対象列として、一意に定まるまで文字を照合する。一意にマッチした場合は対応する値を`val`へ格納する。そうでない場合は`false`を格納し、`err`に[`std::ios_base::failbit`](/reference/ios/ios_base/type-iostate.md)を設定する + + +## 戻り値 +- (1) : 照合に使用しなかった最初の文字を指すイテレータ +- (2)〜(11) : Stage 2で抽出を終えた位置、すなわち変換に使用しなかった最初の文字を指すイテレータ + - 規格が明示的に戻り値を規定しているのは(1)のみだが、これらのオーバーロードも同様のイテレータを返す + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`num_get::get`](get.md) +- [`numpunct`](/reference/locale/numpunct.md) + + +## 参照 +- [LWG Issue 1169. `num_get` not fully compatible with `strto*`](https://cplusplus.github.io/LWG/issue1169) + - C++17で、`float`に`std::strtof`、`long double`に`std::strtold`を使用することが明示され(`std::strtoll`/`std::strtoull`/`std::strtod`は変更なし)、符号なし整数型で表現できない値に対しては(正負によらず)常に表現可能な最大の値を格納する形に整理された。これによりC標準ライブラリと整合するようになった diff --git a/reference/locale/num_get/get.md b/reference/locale/num_get/get.md new file mode 100644 index 0000000000..d55beab5cb --- /dev/null +++ b/reference/locale/num_get/get.md @@ -0,0 +1,94 @@ +# get +* locale[meta header] +* std[meta namespace] +* num_get[meta class] +* function[meta id-type] + +```cpp +public: + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, bool& val) const; // (1) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long& val) const; // (2) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long long& val) const; // (3) C++11 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned short& val) const; // (4) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned int& val) const; // (5) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned long& val) const; // (6) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, unsigned long long& val) const; // (7) C++11 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, float& val) const; // (8) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, double& val) const; // (9) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, long double& val) const; // (10) C++98 + iter_type get(iter_type in, iter_type end, ios_base& str, + ios_base::iostate& err, void*& val) const; // (11) C++98 +``` +* ios_base[link /reference/ios/ios_base.md] +* ios_base::iostate[link /reference/ios/ios_base/type-iostate.md] + +## 概要 +入力イテレータ範囲`[in, end)`から文字列を読み取り、`val`の型に応じた数値・真偽値・ポインタへ変換する。 + +- (1) : `bool`へ変換する +- (2), (3) : 符号付き整数型 (`long`, `long long`) へ変換する +- (4), (5), (6), (7) : 符号なし整数型 (`unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`) へ変換する +- (8), (9), (10) : 浮動小数点数型 (`float`, `double`, `long double`) へ変換する +- (11) : ポインタ (`void*`) へ変換する + + +## 効果 +- (1)〜(11) : [`do_get`](do_get.md)`(in, end, str, err, val)`を呼び出す + + +## 戻り値 +- (1)〜(11) : [`do_get`](do_get.md)`(in, end, str, err, val)`の戻り値。読み取りに使用しなかった最初の文字を指すイテレータとなる + + +## 例 +```cpp example +#include +#include +#include +#include + +int main() +{ + std::istringstream iss{"42"}; + auto& facet = std::use_facet>(iss.getloc()); + + long value = 0; + std::ios_base::iostate err = std::ios_base::goodbit; + std::istreambuf_iterator begin{iss}, end{}; + + facet.get(begin, end, iss, err, value); + + std::cout << value << std::endl; +} +``` +* std::num_get[link /reference/locale/num_get.md] +* std::use_facet[link /reference/locale/use_facet.md] +* get[color ff0000] +* std::ios_base::iostate[link /reference/ios/ios_base/type-iostate.md] +* std::ios_base::goodbit[link /reference/ios/ios_base/type-iostate.md] +* std::istreambuf_iterator[link /reference/iterator/istreambuf_iterator.md] + +### 出力 +``` +42 +``` + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`num_get::do_get`](do_get.md) +- [`numpunct`](/reference/locale/numpunct.md) diff --git a/reference/locale/num_get/op_constructor.md b/reference/locale/num_get/op_constructor.md new file mode 100644 index 0000000000..014cd63302 --- /dev/null +++ b/reference/locale/num_get/op_constructor.md @@ -0,0 +1,71 @@ +# コンストラクタ +* locale[meta header] +* std[meta namespace] +* num_get[meta class] +* function[meta id-type] + +```cpp +explicit num_get(size_t refs = 0); +``` + +## 概要 +`num_get`ファセットオブジェクトを構築する。 + + +## 効果 +基底クラスを[`locale::facet`](/reference/locale/locale/facet.md)`(refs)`で初期化する。 + + +## 備考 +`refs`は、このファセットの参照カウントの初期値である。 + +- `refs == 0`の場合、このファセットを保持する[`locale`](/reference/locale/locale.md)オブジェクトが破棄されるとき、ファセットも破棄される +- `refs == 1`の場合、[`locale`](/reference/locale/locale.md)オブジェクトの破棄によってファセットが破棄されることはない。ファセットの寿命を利用者が管理する場合に使用する + + +## 例 +```cpp example +#include +#include +#include +#include + +// num_getを継承して、独自のファセットを定義する +struct my_num_get : std::num_get { + // 基底クラスのコンストラクタに参照カウントを渡す + explicit my_num_get(std::size_t refs = 0) + : std::num_get(refs) {} +}; + +int main() +{ + std::istringstream iss{"42"}; + + // 独自ファセットを設定したロケールを構築する + std::locale loc{iss.getloc(), new my_num_get{}}; + iss.imbue(loc); + + long value = 0; + iss >> value; + + std::cout << value << std::endl; +} +``` +* std::num_get[link /reference/locale/num_get.md] +* std::locale[link /reference/locale/locale.md] +* iss.getloc()[link /reference/ios/ios_base/getloc.md] +* iss.imbue[link /reference/ios/basic_ios/imbue.md] + +### 出力 +``` +42 +``` + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`locale::facet`](/reference/locale/locale/facet.md) +- [`num_get::get`](get.md) diff --git a/reference/locale/num_get/op_destructor.md b/reference/locale/num_get/op_destructor.md new file mode 100644 index 0000000000..edd7afe99c --- /dev/null +++ b/reference/locale/num_get/op_destructor.md @@ -0,0 +1,29 @@ +# デストラクタ +* locale[meta header] +* std[meta namespace] +* num_get[meta class] +* function[meta id-type] + +```cpp +protected: + ~num_get(); +``` + +## 概要 +`num_get`ファセットオブジェクトを破棄する。 + + +## 備考 +このデストラクタは`protected`であり、仮想関数ではない。そのため`num_get`オブジェクトを、利用者が直接`delete`することはできない。 + +ファセットの寿命は、それを保持する[`locale`](/reference/locale/locale.md)オブジェクトによって管理される。参照カウント([コンストラクタ](op_constructor.md)の`refs`引数)が`0`のファセットは、それを保持する最後の[`locale`](/reference/locale/locale.md)オブジェクトが破棄されるときに破棄される。 + + +## バージョン +### 言語 +- C++98 + + +## 関連項目 +- [`num_get`のコンストラクタ](op_constructor.md) +- [`locale::facet`](/reference/locale/locale/facet.md) diff --git a/reference/map/map/op_at.md b/reference/map/map/op_at.md index c5543b4865..fd8c8362fc 100644 --- a/reference/map/map/op_at.md +++ b/reference/map/map/op_at.md @@ -26,6 +26,18 @@ constexpr T& operator[](K&& x); // (3) C++26 - (3) : `key_compare::is_transparent` が妥当な式であること +## 効果 +- (1) : + - C++03 : `x`と等価なキーを持つ要素が存在しない場合、`value_type(x, T())`を挿入する + - C++17 : [`try_emplace`](try_emplace.md)`(x).first->second`と等価 +- (2) : + - C++11 : `x`と等価なキーを持つ要素が存在しない場合、`value_type(`[`move`](/reference/utility/move.md)`(x), T())`を挿入する + - C++17 : [`try_emplace`](try_emplace.md)`(`[`move`](/reference/utility/move.md)`(x)).first->second`と等価 +- (1), (2) : + - C++17 : 要素(`value_type`)はアロケータを通じて一体で構築される +- (3) : `try_emplace(`[`forward`](/reference/utility/forward.md)`(x)).first->second`と等価 + + ## 戻り値 キー`x`に対応する値を返す。対応する要素が存在しない場合は、要素を値初期化して参照を返す。 @@ -79,3 +91,6 @@ a - [P2363R5 Extending associative containers with the remaining heterogeneous overloads](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html) - C++26で`template `のバージョンが追加された - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) +- [LWG Issue 2469. Wrong specification of Requires clause of `operator[]` for `map` and `unordered_map`](https://cplusplus.github.io/LWG/issue2469) + - C++17で、(1), (2)の効果が[`try_emplace`](try_emplace.md)を用いて規定され、要素を`value_type`として一体で構築する矛盾のない要件へ整理された + - 元の要件は`key_type`と`mapped_type`を別々に構築することを求めており、要素が`value_type`として一体で構築されるという規定と矛盾していた。ただし修正後の文言が用いる[`try_emplace`](try_emplace.md)はC++17で追加されたメンバ関数であるため、この規定自体をそれ以前のバージョンへ遡及して適用することはできない diff --git a/reference/memory/allocator_arg_t.md b/reference/memory/allocator_arg_t.md index 2480d2d3e8..938866764b 100644 --- a/reference/memory/allocator_arg_t.md +++ b/reference/memory/allocator_arg_t.md @@ -35,3 +35,8 @@ namespace std { - [`std::tuple`](/reference/tuple/tuple.md)クラス - [`std::promise`](/reference/future/promise.md)クラス - [`std::function`](/reference/functional/function.md)クラス + + +## 参照 +- [LWG Issue 2510. Tag types should not be `DefaultConstructible`](https://cplusplus.github.io/LWG/issue2510) + - C++17で、`{}`による暗黙構築を防ぐため、明示的なデフォルトコンストラクタ(`explicit allocator_arg_t() = default;`)が追加された diff --git a/reference/memory/make_shared.md b/reference/memory/make_shared.md index 1e8afcc179..8e7b208703 100644 --- a/reference/memory/make_shared.md +++ b/reference/memory/make_shared.md @@ -145,9 +145,12 @@ int main() { - [std::make_shared から private コンストラクタを呼び出す - 野良C++erの雑記帳](http://d.hatena.ne.jp/gintenlabo/20131211/1386771626) - [P0674R1 Extending `make_shared` to support arrays](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0674r1.html) - [P3037R6 `constexpr std::shared_ptr` and friends](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) +- [LWG Issue 2696. Interaction between `make_shared` and `enable_shared_from_this` is underspecified](https://cplusplus.github.io/LWG/issue2696) + - C++17で、`make_shared`/`allocate_shared`が呼び出すコンストラクタも`shared_from_this`を有効にすることが明確化された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元の規定はpublicなコンストラクタについてのみ`shared_from_this`の有効化を述べており、これらの関数が使う非publicなコンストラクタについては未規定だったが、処理系は当初から有効化していたため - [LWG Issue 3005. Destruction order of arrays by `make_shared`/`allocate_shared` only recommended?](https://cplusplus.github.io/LWG/issue3005) - C++20で、配列要素の破棄順が非規範的な推奨から規範的要件に格上げされ、元の構築順の逆順で破棄されることが明確化された - [LWG Issue 3008. `make_shared` (sub)object destruction semantics are not specified](https://cplusplus.github.io/LWG/issue3008) - C++20で、生成した(サブ)オブジェクトの破棄方法(`make_shared`は式`pv->~U()`による破棄)が明示的に規定された - [LWG Issue 4451. `make_shared` should not refer to a type `U[N]` for runtime N](https://cplusplus.github.io/LWG/issue4451) - - C++26で、`N`が実行時の値である配列版において、結果を「`U[N]`型のオブジェクト」ではなく「[`remove_extent_t`](../type_traits/remove_extent.md)``型の`N`要素の配列」と表現するよう文言が修正された(実行時サイズの`U[N]`は妥当な型ではないため) \ No newline at end of file + - C++26で、`N`が実行時の値である配列版において、結果を「`U[N]`型のオブジェクト」ではなく「[`remove_extent_t`](../type_traits/remove_extent.md)``型の`N`要素の配列」と表現するよう文言が修正された(実行時サイズの`U[N]`は妥当な型ではないため) diff --git a/reference/memory/raw_storage_iterator/op_assign.md b/reference/memory/raw_storage_iterator/op_assign.md index bfe4466c8f..ccbdb19be0 100644 --- a/reference/memory/raw_storage_iterator/op_assign.md +++ b/reference/memory/raw_storage_iterator/op_assign.md @@ -7,7 +7,8 @@ * cpp20removed[meta cpp] ```cpp -raw_storage_iterator& operator=(const T& element); +raw_storage_iterator& operator=(const T& element); // (1) C++98 +raw_storage_iterator& operator=(T&& element); // (2) C++17 ``` このクラスは、C++17から非推奨となり、C++20で削除された。 @@ -17,8 +18,14 @@ raw_storage_iterator& operator=(const T& element); 値を出力する +## テンプレートパラメータ制約 +- (1) : 型`T`がコピー構築可能(Cpp17CopyConstructible)であること +- (2) : 型`T`がムーブ構築可能(Cpp17MoveConstructible)であること + + ## 効果 -現在イテレータが指している位置に、`element`から`T`型オブジェクトを構築する。 +- (1) : 現在イテレータが指している位置に、`element`をコピーして`T`型オブジェクトを構築する。 +- (2) : 現在イテレータが指している位置に、`std::move(element)`をムーブして`T`型オブジェクトを構築する。 ## 戻り値 @@ -28,3 +35,5 @@ raw_storage_iterator& operator=(const T& element); ## 参照 - [P0174R2 Deprecating Vestigial Library Parts in C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0174r2.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2127. Move-construction with `raw_storage_iterator`](https://cplusplus.github.io/LWG/issue2127) + - C++17で、ムーブ構築のためのオーバーロード (2) が追加され、あわせて各オーバーロードにクラステンプレートパラメータ`T`のコピー構築可能/ムーブ構築可能の制約が明記された diff --git a/reference/memory/shared_ptr/dynamic_pointer_cast.md b/reference/memory/shared_ptr/dynamic_pointer_cast.md index a65a5eaaa6..4f7611214c 100644 --- a/reference/memory/shared_ptr/dynamic_pointer_cast.md +++ b/reference/memory/shared_ptr/dynamic_pointer_cast.md @@ -26,6 +26,24 @@ namespace std { `shared_ptr` で管理するインスタンスに対して `dynamic_cast` を行う。 +## 適格要件 +- (1) : + - C++11 : 式`dynamic_cast(r.`[`get()`](get.md)`)`が適格であること + - C++17 : 式`dynamic_cast((U*)0)`が適格であること + - C++20 : 式`dynamic_cast((U*)nullptr)`と、式`dynamic_cast::element_type*>(r.`[`get()`](get.md)`)`が、いずれも適格であること +- (2) : + - C++20 : (1)のC++20と同じ + + +## 事前条件 +- (1) : + - C++11 : 式`dynamic_cast(r.`[`get()`](get.md)`)`が定義された動作をすること + - C++17 : 式`dynamic_cast((U*)0)`が定義された動作をすること + - C++20 : 式`dynamic_cast::element_type*>(r.`[`get()`](get.md)`)`が定義された動作をすること +- (2) : + - C++20 : (1)のC++20と同じ + + ## 戻り値 - `r` が空であった場合、この関数は空の `shared_ptr` を返却する。 - (1) : @@ -102,5 +120,8 @@ B::call() ## 参照 +- [LWG Issue 2964. Apparently redundant requirement for `dynamic_pointer_cast`](https://cplusplus.github.io/LWG/issue2964) + - C++20で、実際にキャストされる式`dynamic_cast::element_type*>(r.get())`が適格で定義された動作をすることが要件として追加された(`dynamic_cast((U*)nullptr)`が適格であるという要件は残る) + - この修正は欠陥報告(DR)であり、C++17にも遡及して適用される。C++17では要件がヌルポインタに対する`dynamic_cast((U*)0)`のみを対象としており、ヌルポインタへの`dynamic_cast`は適格であれば常にヌルポインタを返すため、定義された動作であることの要件が実質的に無意味になっていた。実際にキャストされる式に対する要件を課す意図だったため - [LWG Issue 2996. Missing rvalue overloads for `shared_ptr` operations](https://wg21.cmeerw.net/lwg/issue2996) - [P3037R6 `constexpr std::shared_ptr` and friends](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) \ No newline at end of file diff --git a/reference/memory/shared_ptr/op_constructor.md b/reference/memory/shared_ptr/op_constructor.md index a6cf28f769..db27eda369 100644 --- a/reference/memory/shared_ptr/op_constructor.md +++ b/reference/memory/shared_ptr/op_constructor.md @@ -144,7 +144,9 @@ shared_ptr(shared_ptr&& r, - 型`T`が配列である場合、式`delete[] p`が妥当であること。 - 型`T`が`U[N]`形式である場合、関数ポインタ配列`Y(*)[N]`は`T*`に変換可能である。 - 型`T`が`U[]`形式である場合、関数ポインタ配列`Y(*)[]`は`T*`に変換可能である。 -- (3), (4), (5), (6) : `p`が`T*`に変換可能であること。`Deleter`がコピー構築可能な型であり、そのコピーコンストラクタとデストラクタが例外を投げないこと。`d(p)`という式が妥当であること。 +- (3), (4), (5), (6) : `p`が`T*`に変換可能であること。`d`および`std::`[`move`](/reference/utility/move.md)`(d)`から型`Deleter`の削除子を構築する操作が例外を投げないこと。`d(p)`という式が適格であり、定義された動作をし、例外を投げないこと。 + - C++11 : `Deleter`がコピー構築可能であること + - C++17 : `Deleter`がムーブ構築可能であること。また、`Deleter`のデストラクタが例外を投げないという要件は削除された - C++17 : 型`T`が配列である場合、式`delete[] p`が妥当であること。型`T`が`U[N]`形式である場合、関数ポインタ配列`Y(*)[N]`は`T*`に変換可能である。 - (9) C++11 : `Y*`が`T*`に暗黙変換可能でない場合、この関数はオーバーロード解決から除外される。 - (9) C++17 : `Y*`が`T*`と互換でない場合、この関数はオーバーロード解決から除外される。 @@ -340,6 +342,16 @@ int main() - [N4190 Removing `auto_ptr`, `random_shuffle()`, And Old `` Stuff](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190.htm) - [P0414R1 Merging `shared_ptr` changes from Library Fundamentals to C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0414r1.html) - [P0497R0 Fixes to `shared_ptr` support for arrays](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0497r0.html) -- [LWG Issue 2996. Missing rvalue overloads for `shared_ptr` operations](https://wg21.cmeerw.net/lwg/issue2996) - [LWG Issue 2365. Missing `noexcept` in `shared_ptr::shared_ptr(nullptr_t)`](https://wg21.cmeerw.net/lwg/issue2365) -- [P3037R6 `constexpr std::shared_ptr` and friends](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) \ No newline at end of file +- [LWG Issue 2685. `shared_ptr` deleters must not throw on move construction](https://cplusplus.github.io/LWG/issue2685) + - C++17で、削除子`D`の構築(`CopyConstructible`は維持)が例外を投げないという要件が追加された +- [LWG Issue 2802. `shared_ptr` constructor requirements for a deleter](https://cplusplus.github.io/LWG/issue2802) + - C++17で、削除子`D`の要件が`CopyConstructible`から`MoveConstructible`に緩和され、`d`および`std::move(d)`からの構築が例外を投げないこと、`d(p)`が適格であり定義された動作をし、例外を投げないことが規定された。あわせて「`D`のデストラクタが例外を投げない」要件は削除された +- [LWG Issue 2874. Constructor `shared_ptr::shared_ptr(Y*)` should be constrained](https://cplusplus.github.io/LWG/issue2874) + - C++17で、ポインタから構築するコンストラクタが、`delete p`(配列版は`delete[] p`)が妥当で`Y*`が`T*`と互換な場合のみオーバーロード解決に参加するよう制約化された +- [LWG Issue 2875. `shared_ptr::shared_ptr(Y* | D | […])` constructors should be constrained](https://cplusplus.github.io/LWG/issue2875) + - C++17で、削除子を取るコンストラクタが、`D`がムーブ構築可能で`d(p)`が妥当などの条件を満たす場合のみオーバーロード解決に参加するよう制約化された +- [LWG Issue 2876. `shared_ptr::shared_ptr(const weak_ptr&)` constructor should be constrained](https://cplusplus.github.io/LWG/issue2876) + - C++17で、`weak_ptr`から構築するコンストラクタ(12)が、`Y*`が`T*`と互換な場合のみオーバーロード解決に参加するよう制約化され、`is_constructible`が正しい結果を返すようになった +- [LWG Issue 2996. Missing rvalue overloads for `shared_ptr` operations](https://wg21.cmeerw.net/lwg/issue2996) +- [P3037R6 `constexpr std::shared_ptr` and friends](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) diff --git a/reference/memory/shared_ptr/op_less.md b/reference/memory/shared_ptr/op_less.md index 3ed65ad637..9bf2bc0c44 100644 --- a/reference/memory/shared_ptr/op_less.md +++ b/reference/memory/shared_ptr/op_less.md @@ -86,3 +86,6 @@ true - [P0497R0 Fixes to `shared_ptr` support for arrays](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0497r0.html) - [P1614R2 The Mothership has Landed](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1614r2.html) - C++20での三方比較演算子の追加と、関連する演算子の自動導出 +- [LWG Issue 2908. The less-than operator for shared pointers could do more](https://cplusplus.github.io/LWG/issue2908) + - C++17で、合成ポインタ型を用いる規定から`less<>`(透過的な`less`)を用いる形に規定が簡素化された。比較可能な組み合わせ自体は変わらない(コア言語の`operator<`が常に合成ポインタ型を形成するため、元の規定でも同等に一般的だった) + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。観測可能な挙動を変えない規定の簡素化であるため diff --git a/reference/memory/unique_ptr/op_constructor.md b/reference/memory/unique_ptr/op_constructor.md index 83a5dc60c6..bb89acf383 100644 --- a/reference/memory/unique_ptr/op_constructor.md +++ b/reference/memory/unique_ptr/op_constructor.md @@ -209,9 +209,11 @@ int main() - [N4089 Safe conversions in `unique_ptr`, revision 2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4089.pdf) - [LWG Issue 2520 : N4089 broke initializing `unique_ptr` from a nullptr](https://wg21.cmeerw.net/lwg/issue2520) - [LWG Issue 2801. Default-constructibility of `unique_ptr`](https://wg21.cmeerw.net/lwg/issue2948) -- [LWG Issue 2905. `is_constructible_v, P, D const &>` should be false when D is not copy constructible](https://wg21.cmeerw.net/lwg/issue2905) - [LWG Issue 2899. `is_(nothrow_)move_constructible` and `tuple`, `optional` and `unique_ptr`](https://cplusplus.github.io/LWG/issue2899) - C++20で、ムーブコンストラクタ(5)が、デリータ型`D`がムーブ構築可能でない場合はオーバーロード解決に参加しないよう制約化され、`is_move_constructible>`が正しく判定されるようになった +- [LWG Issue 2905. `is_constructible_v, P, D const &>` should be false when D is not copy constructible](https://wg21.cmeerw.net/lwg/issue2905) +- [LWG Issue 2944. LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception](https://cplusplus.github.io/LWG/issue2944) + - C++20で、LWG 2905の文言簡略化で失われた「デリータの構築が例外を送出しない」要件が復元された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される +- [P2273R3 Making `std::unique_ptr` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2273r3.pdf) - [LWG Issue 3632. `unique_ptr` "_Mandates_: This constructor is not selected by class template argument deduction"](https://cplusplus.github.io/LWG/issue3632) - C++23で、クラステンプレート実引数推論(CTAD)による選択を防ぐ仕様が、Mandates指定から引数型を`type_identity_t`とする方式へ書き換えられた(観測可能な振る舞いは変わらない) -- [P2273R3 Making `std::unique_ptr` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2273r3.pdf) diff --git a/reference/memory/weak_ptr.md b/reference/memory/weak_ptr.md index 548e7d3c10..476eab7935 100644 --- a/reference/memory/weak_ptr.md +++ b/reference/memory/weak_ptr.md @@ -50,7 +50,7 @@ namespace std { | 名前 | 説明 | 対応バージョン | |----------------|-----------|-------| -| `element_type` | 要素型`T` | C++11 | +| `element_type` | 監視するインスタンスの型
C++11 : `T`
C++17 : [`remove_extent_t`](/reference/type_traits/remove_extent.md)``(配列型`U[N]`, `U[]`に対しては`U`) | C++11 | ## 非メンバ関数 @@ -114,3 +114,5 @@ shared_ptr managed object deleted. - [Visual C++](/implementation.md#visual_cpp): 2008 (TR1) [mark verified], 2010 [mark verified], 2012 [mark verified], 2013 [mark verified] ## 参照 +- [LWG Issue 3001. `weak_ptr::element_type` needs `remove_extent_t`](https://cplusplus.github.io/LWG/issue3001) + - C++20で、`shared_ptr`の配列対応に合わせて`element_type`が`remove_extent_t`となるよう修正された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/memory/weak_ptr/owner_before.md b/reference/memory/weak_ptr/owner_before.md index e522bf69a8..c97aca82b6 100644 --- a/reference/memory/weak_ptr/owner_before.md +++ b/reference/memory/weak_ptr/owner_before.md @@ -84,6 +84,8 @@ false - [N2637 Revisiting std::shared_ptr comparison](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2637.pdf) - [LWG Issue 1406. Support hashing smart-pointers based on owner](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1406) - [LWG Issue 2873. Add `noexcept` to several `shared_ptr` related functions](https://wg21.cmeerw.net/lwg/issue2873) +- [LWG Issue 2942. LWG 2873's resolution missed `weak_ptr::owner_before`](https://cplusplus.github.io/LWG/issue2942) + - C++20で、LWG 2873で`shared_ptr::owner_before`等に付いた`noexcept`が`weak_ptr::owner_before`にも付与された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される - [P3037R6 `constexpr std::shared_ptr` and friends](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) - [LWG Issue 4557. Remove `constexpr` from `owner_less` and `owner_before`](https://cplusplus.github.io/LWG/issue4557) - C++26で、P3037R6により一旦付与された`constexpr`指定が取り消され、`owner_before`と`owner_less`の`operator()`は`constexpr`ではなくなった diff --git a/reference/memory_resource/memory_resource.md b/reference/memory_resource/memory_resource.md index 5fdb1744d2..a214150817 100644 --- a/reference/memory_resource/memory_resource.md +++ b/reference/memory_resource/memory_resource.md @@ -187,3 +187,5 @@ false - [P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html) - [P0337r0 | Delete operator= for polymorphic_allocator](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0337r0.html) - [Working Draft, C++ Extensions for Library Fundamentals, Version 2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.synop) +- [LWG Issue 2724. The `protected virtual` member functions of `memory_resource` should be `private`](https://cplusplus.github.io/LWG/issue2724) + - C++17の策定中に、`do_allocate`/`do_deallocate`/`do_is_equal`のアクセスが`protected`から`private`に変更された(派生クラスから直接呼ぶものではないため) diff --git a/reference/numeric/exclusive_scan.md b/reference/numeric/exclusive_scan.md index ac3b0f1390..e80a79a13d 100644 --- a/reference/numeric/exclusive_scan.md +++ b/reference/numeric/exclusive_scan.md @@ -194,3 +194,5 @@ int main() - この関数の用途として、[`std::multiset`](/reference/set/multiset.md)のような構成になっているシーケンスから、それぞれのキーがはじまるインデックスのリストを取得するために使用できる - [P1645R1 `constexpr` for `` algorithms](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1645r1.html) - C++20で、並列バージョン以外の数値計算アルゴリズムが`constexpr`対応した +- [LWG Issue 2687. `{inclusive,exclusive}_scan` misspecified](https://cplusplus.github.io/LWG/issue2687) + - C++17で、各出力位置が対象とする入力範囲の境界のoff-by-oneが修正され、正しい包括/排他スキャンの意味論となった diff --git a/reference/numeric/inclusive_scan.md b/reference/numeric/inclusive_scan.md index 562ecbe632..11571fd65b 100644 --- a/reference/numeric/inclusive_scan.md +++ b/reference/numeric/inclusive_scan.md @@ -239,5 +239,7 @@ int main() - [P0574R1: Algorithm Complexity Constraints and Parallel Overloads](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0574r1.html) - [P1645R1 `constexpr` for `` algorithms](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1645r1.html) - C++20で、並列バージョン以外の数値計算アルゴリズムが`constexpr`対応した +- [LWG Issue 2687. `{inclusive,exclusive}_scan` misspecified](https://cplusplus.github.io/LWG/issue2687) + - C++17で、各出力位置が対象とする入力範囲の境界のoff-by-oneが修正され、正しい包括/排他スキャンの意味論となった - [LWG Issue 3222. P0574R1 introduced preconditions on non-existent parameters](https://cplusplus.github.io/LWG/issue3222) - C++20で、init無しオーバーロードの事前条件が、存在しないテンプレートパラメータを参照していた誤りを修正するeditorialな整理が行われた diff --git a/reference/optional/optional/op_constructor.md b/reference/optional/optional/op_constructor.md index 8946e104f0..1c7a3b3822 100644 --- a/reference/optional/optional/op_constructor.md +++ b/reference/optional/optional/op_constructor.md @@ -264,7 +264,7 @@ int main() - [N3406 A proposal to add a utility class to represent optional objects (Revision 2)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406.html) - [LWG Issue 2756. `optional` should `forward` `T`'s implicit conversions](https://wg21.cmeerw.net/lwg/issue2756) - [LWG Issue 2842. `in_place_t` check for `optional::optional(U&&)` should decay `U`](https://wg21.cmeerw.net/lwg/issue2842) - - 説明の簡略化のため、このオーバーロードで`in_place_t`への言及は現在していない + - C++17で、変換コンストラクタの制約が、`U`をdecayしてから[`std::in_place_t`](/reference/utility/in_place_t.md)と比較するよう修正された。このページでは説明の簡略化のため、このオーバーロードで`in_place_t`への言及はしていない - [LWG Issue 2900. The copy and move constructors of `optional` are not `constexpr`](https://wg21.cmeerw.net/lwg/issue2900) - [P0777R1 Treating Unnecessary `decay`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0777r1.pdf) - [P0892R2 `explicit(bool)`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0892r2.html) @@ -273,3 +273,5 @@ int main() - [P2231R1 Missing `constexpr` in `std::optional` and `std::variant`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2231r1.html) - [P2988R12 `std::optional`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2988r12.pdf) - C++26で参照型`T&`に対する部分特殊化を追加 +- [LWG Issue 2900. The copy and move constructors of `optional` are not constexpr](https://cplusplus.github.io/LWG/issue2900) + - C++17の策定中に、コピーコンストラクタ(3)・ムーブコンストラクタ(4)が`constexpr`となった(それぞれ`T`がトリビアルにコピー/ムーブ構築可能な場合に定数式で使用可能) diff --git a/reference/ostream/basic_ostream/op_ostream_free.md b/reference/ostream/basic_ostream/op_ostream_free.md index fdca09f75f..ec4e124500 100644 --- a/reference/ostream/basic_ostream/op_ostream_free.md +++ b/reference/ostream/basic_ostream/op_ostream_free.md @@ -72,6 +72,11 @@ namespace std { - 文字に対するオーバーロードは、書式化出力関数である。 - 文字列に対するオーバーロードは、書式化出力関数である。 +## テンプレートパラメータ制約 +- (25) : + - C++17 : 式`os << x`が適格であること + + ## 効果 ### (1)-(5) 文字の書式化出力 @@ -111,7 +116,7 @@ namespace std { ## 備考 -- (25) の形式は C++11 から追加されたが、より使いやすくするための変更が提案されている。 +- (25) の形式は C++11 から追加され、C++17 で式`os << x`が適格な場合のみオーバーロード解決に参加するよう制約化された。 [LWG1203. More useful rvalue stream insertion](https://wg21.cmeerw.net/lwg/issue1203) - (3)、および、(15) の形式は、オーバーロード解決時の曖昧さ解消のために存在する。 (これらが存在しないと、`CharT` が `char` 型の場合に、(1) と (2)、あるいは (13) と (14) が同じ優先順位となりオーバーロード解決に失敗してしまう) @@ -290,3 +295,5 @@ int main() ## 参照 [P1423R3: char8_t backward compatibility remediation](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html) +- [LWG Issue 2534. Constrain rvalue stream operators](https://cplusplus.github.io/LWG/issue2534) + - C++17で、右辺値ストリーム版`operator<<`が`os << x`が妥当な場合のみオーバーロード解決に参加するよう制約化され、SFINAEでのストリーム可否判定が正しく機能するようになった diff --git a/reference/queue/priority_queue.md b/reference/queue/priority_queue.md index b3b1c8dfd5..bfba8da76a 100644 --- a/reference/queue/priority_queue.md +++ b/reference/queue/priority_queue.md @@ -38,6 +38,10 @@ namespace std { 以下のリファレンス中では、テンプレート引数として同じ名前を用いる。 +## 適格要件 +`T`が`Container::value_type`と同じ型であること。 + + ## メンバ関数 | 名前 | 説明 | 対応バージョン | @@ -72,6 +76,7 @@ namespace std { | `const_reference` | `Container::const_reference` | C++11 | | `size_type` | `Container::size_type` | | | `container_type` | `Container` | | +| `value_compare` | `Compare` | C++17 | ## 非メンバ関数 @@ -201,3 +206,10 @@ int main() - [`std::pop_heap`](/reference/algorithm/pop_heap.md) - [`std::make_heap`](/reference/algorithm/make_heap.md) - [`std::sort_heap`](/reference/algorithm/sort_heap.md) + + +## 参照 +- [LWG Issue 2566. Requirements on the first template parameter of container adaptors](https://cplusplus.github.io/LWG/issue2566) + - C++17で、テンプレートパラメータ`T`が`Container::value_type`と同じ型であることが規定された +- [LWG Issue 2684. `priority_queue` lacking comparator `typedef`](https://cplusplus.github.io/LWG/issue2684) + - C++17で、他の順序付きコンテナと同様に、比較関数型のメンバ型`value_compare`が追加された diff --git a/reference/queue/priority_queue/op_constructor.md b/reference/queue/priority_queue/op_constructor.md index 6d22cbc4e9..6f17f84b5f 100644 --- a/reference/queue/priority_queue/op_constructor.md +++ b/reference/queue/priority_queue/op_constructor.md @@ -368,6 +368,9 @@ que5 : 5 4 3 2 1 ## 参照 - [P0935R0 Eradicating unnecessarily explicit default constructors from the standard library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0935r0.html) +- [LWG Issue 2537. Constructors for `priority_queue` taking allocators should call `make_heap`](https://cplusplus.github.io/LWG/issue2537) + - C++17で、アロケータを受け取るコンストラクタでも`make_heap`を呼び出すことが明記された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元の文言を厳密に読むと呼び出し側がヒープ化済みのコンテナを渡す必要があるという意図しない解釈になり、処理系は当初から`make_heap`を呼んでいたため - [LWG Issue 3506. Missing allocator-extended constructors for `priority_queue`](https://cplusplus.github.io/LWG/issue3506) - C++23で、イテレータ範囲を受け取るアロケータ拡張コンストラクタ(15)〜(17)が追加された - [LWG Issue 3522. Missing requirement on `InputIterator` template parameter for `priority_queue` constructors](https://cplusplus.github.io/LWG/issue3522) diff --git a/reference/queue/queue.md b/reference/queue/queue.md index 19ef4b48c6..346764224f 100644 --- a/reference/queue/queue.md +++ b/reference/queue/queue.md @@ -34,6 +34,10 @@ namespace std { 以下のリファレンス中では、テンプレート引数として同じ名前を用いる。 +## 適格要件 +`T`が`Container::value_type`と同じ型であること。 + + ## メンバ関数 | 名前 | 説明 | 対応バージョン | @@ -121,3 +125,5 @@ int main() ``` ## 参照 +- [LWG Issue 2566. Requirements on the first template parameter of container adaptors](https://cplusplus.github.io/LWG/issue2566) + - C++17で、テンプレートパラメータ`T`が`Container::value_type`と同じ型であることが規定された diff --git a/reference/regex/match_results.md b/reference/regex/match_results.md index 01c56c6944..0781853346 100644 --- a/reference/regex/match_results.md +++ b/reference/regex/match_results.md @@ -53,6 +53,7 @@ namespace std { さらに、マッチした結果を用いた書式出力機能も有する([`format`](match_results/format.md))。 `match_results` はアロケータ対応コンテナの要件のすべてと、シーケンスコンテナの要件のうち読み取り専用の操作に加え、コピー代入・ムーブ代入・[`swap`](match_results/swap.md) をサポートしている。 +ただし [`operator==`](match_results/op_equal.md) の意味論はコンテナの要件とは異なる。要素ごとの比較([`equal`](/reference/algorithm/equal.md)による比較)とは一致しないため、コンテナとしての等価性の意味論には従わない。 `match_results` オブジェクトからメンバ関数で取得できるイテレータについて規格では特に言及されていないが、[`operator[]`](match_results/op_at.md) が使用できることから通常ランダムアクセスイテレータであるもの考えても差し支えないものと思われる。 @@ -196,6 +197,9 @@ The C++14 is very cool!! ## 参照 - [LWG Issue 2183. Muddled allocator requirements for `match_results` constructors](https://cplusplus.github.io/LWG/issue2183) - - コンストラクタのアロケータ要件が整理され、`match_results`がアロケータ対応コンテナの規則に従うことが明確化された。C++20に取り込まれたが、矛盾した仕様文言の修正であり実装の挙動は変わらない + - C++20で、コンストラクタのアロケータ要件が整理され、`match_results`がアロケータ対応コンテナの規則に従うことが明確化された。C++20に取り込まれたが、矛盾した仕様文言の修正であり実装の挙動は変わらない - [LWG Issue 2184. Muddled allocator requirements for `match_results` assignments](https://cplusplus.github.io/LWG/issue2184) - - `match_results`が、読み取り専用のシーケンスコンテナ操作に加えてコピー代入・ムーブ代入・swapをサポートすることが明確化された。C++20に取り込まれたが、これらの演算子自体はC++11から存在しており、矛盾した仕様文言の修正であるため実装の挙動は変わらない + - C++20で、`match_results`が読み取り専用のシーケンスコンテナ操作に加えてコピー代入・ムーブ代入・swapをサポートすることが明確化された。C++20に取り込まれたが、これらの演算子自体はC++11から存在しており、矛盾した仕様文言の修正であるため実装の挙動は変わらない +- [LWG Issue 2589. `match_results` can't satisfy the requirements of a container](https://cplusplus.github.io/LWG/issue2589) + - C++17で、`match_results`は`operator==`の意味論がコンテナ要件と異なる(要素ごとの比較と一致しない)ことが明確化され、コンテナ要件を「満たす」がその比較意味論は例外である旨に整理された + - この修正は欠陥報告(DR)であり、C++11に遡及して適用される。`operator==`の意味論とコンテナ要件が両立しないという充足不可能な要件記述の修正であり、`operator==`自体の挙動は変わらないため diff --git a/reference/regex/regex_match.md b/reference/regex/regex_match.md index fa1ca08446..1bfaacfb79 100644 --- a/reference/regex/regex_match.md +++ b/reference/regex/regex_match.md @@ -208,3 +208,6 @@ GCC(libstdc++) では、4.9.2 までは (4) の形式は存在しない。 ## 参照 * [C++の正規表現ライブラリ: std::regex | 本の虫](https://cpplover.blogspot.jp/2015/01/c-stdregex.html) +* [LWG Issue 2273. `regex_match` ambiguity](https://cplusplus.github.io/LWG/issue2273) + * C++17で、マッチ判定において文字列全体にマッチする候補のみを考慮することが明確化された + * この修正は欠陥報告(DR)であり、C++11に遡及して適用される。元の文言が2通りに解釈できる曖昧なもので、規格制定当初からの意図(および主要な処理系の挙動)を明文化したものであるため diff --git a/reference/scoped_allocator/scoped_allocator_adaptor.md b/reference/scoped_allocator/scoped_allocator_adaptor.md index 22ad337c5a..d3891f9b1b 100644 --- a/reference/scoped_allocator/scoped_allocator_adaptor.md +++ b/reference/scoped_allocator/scoped_allocator_adaptor.md @@ -44,6 +44,8 @@ namespace std { |-----------------------------------------|----------------------------------------------|-------| | [`(constructor)`][constructor] | コンストラクタ | C++11 | | `~scoped_allocator_adaptor() = default` | デストラクタ | C++11 | +| `operator=(const scoped_allocator_adaptor&) = default` | コピー代入演算子 | C++17 | +| `operator=(scoped_allocator_adaptor&&) = default` | ムーブ代入演算子 | C++17 | | [`inner_allocator`][inner_allocator] | 内側のアロケータを取得する | C++11 | | [`outer_allocator`][outer_allocator] | 外側のアロケータを取得する | C++11 | | [`allocate`][allocate] | メモリを確保する | C++11 | @@ -274,3 +276,5 @@ element allocator : 2 - [N2554 The Scoped Allocator Model (Rev 2)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf) - [Scoped allocators - C++11 FAQ](http://www.stroustrup.com/C++11FAQ.html#scoped-allocator) - [N4258 Cleaning-up noexcept in the Library, Rev 3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4258.pdf) +- [LWG Issue 2476. `scoped_allocator_adaptor` is not assignable](https://cplusplus.github.io/LWG/issue2476) + - C++17で、デフォルト定義されたコピー代入演算子・ムーブ代入演算子がクラス定義に追加され、このアダプタ(およびそれを使うコンテナ)が代入可能になった diff --git a/reference/scoped_allocator/scoped_allocator_adaptor/op_constructor.md b/reference/scoped_allocator/scoped_allocator_adaptor/op_constructor.md index 3a48955886..57434b60c1 100644 --- a/reference/scoped_allocator/scoped_allocator_adaptor/op_constructor.md +++ b/reference/scoped_allocator/scoped_allocator_adaptor/op_constructor.md @@ -37,8 +37,16 @@ scoped_allocator_adaptor( - (6) : 変換可能な外側のアロケータを持つ`scoped_allocator_adaptor`オブジェクトからのムーブ構築。 -## 要件 -- (2), (5), (6) : クラステンプレートのパラメータ`OuterAlloc`は、テンプレートパラメータの型`OuterA2`から構築可能であること。 +## テンプレートパラメータ制約 +- (2) : + - C++11 : クラステンプレートのパラメータ`OuterAlloc`が、テンプレートパラメータの型`OuterA2`から構築可能であること + - C++17 : [`is_constructible_v`](/reference/type_traits/is_constructible.md)``が`true`であること +- (5) : + - C++11 : `OuterAlloc`が`OuterA2`から構築可能であること + - C++17 : [`is_constructible_v`](/reference/type_traits/is_constructible.md)``が`true`であること +- (6) : + - C++11 : `OuterAlloc`が`OuterA2`から構築可能であること + - C++17 : [`is_constructible_v`](/reference/type_traits/is_constructible.md)``が`true`であること ## 効果 @@ -114,3 +122,9 @@ int main() - [GCC](/implementation.md#gcc): 4.7.3 [mark verified] - [ICC](/implementation.md#icc): ?? - [Visual C++](/implementation.md#visual_cpp): ?? + + +## 参照 +- [LWG Issue 2782. `scoped_allocator_adaptor` constructors must be constrained](https://cplusplus.github.io/LWG/issue2782) + - C++17で、(2), (5), (6)の各コンストラクタが、C++11では単なる要件だった「`OuterAlloc`が`OuterA2`から構築可能」をオーバーロード解決に参加する条件(制約)として規定するよう変更され、非互換なアロケータ型間の暗黙変換が排除された + - (5)の制約は`is_constructible_v`、(2)と(6)の制約は`is_constructible_v`である diff --git a/reference/stack/stack.md b/reference/stack/stack.md index 38a907bb79..c8cc57b01d 100644 --- a/reference/stack/stack.md +++ b/reference/stack/stack.md @@ -30,6 +30,10 @@ namespace std { - `Container`: 要素へのアクセス・保存に用いる内部実装のコンテナクラス +## 適格要件 +`T`が`Container::value_type`と同じ型であること。 + + ## メンバ関数 | 名前 | 説明 | 対応バージョン | @@ -116,4 +120,6 @@ int main () 3 2 1 ``` -### 参照 +## 参照 +- [LWG Issue 2566. Requirements on the first template parameter of container adaptors](https://cplusplus.github.io/LWG/issue2566) + - C++17で、テンプレートパラメータ`T`が`Container::value_type`と同じ型であることが規定された diff --git a/reference/string/basic_string.md b/reference/string/basic_string.md index 8d675370c2..c116a2a003 100644 --- a/reference/string/basic_string.md +++ b/reference/string/basic_string.md @@ -62,6 +62,11 @@ namespace std { - 異体字切り換えシーケンス (IVS) +## 適格要件 +- C++17 : `traits::char_type`が`charT`と同じ型であること + - C++03からC++14までは、要件ではなく注記として述べられていた + + ## メンバ関数 ### 構築・破棄 @@ -165,7 +170,7 @@ namespace std { | 名前 | 説明 | 対応バージョン | |---------------------|----------------|------| | `traits_type` | 文字特性型 `traits` | | -| `value_type` | 文字型 `traits::char_type` | | +| `value_type` | 文字型
C++03 : `traits::char_type`
C++17 : `charT` | | | `allocator_type` | アロケータ型 `Allocator` | | | `size_type` | 要素数を表す符号なし整数型。
`allocator_traits::size_type` | | | `difference_type` | イテレータの差を表す符号付き整数型。 `allocator_traits::difference_type` | | @@ -306,3 +311,6 @@ int main() - [N2668 Concurrency Modifications to Basic String](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2668.htm) - C++11で、`basic_string`の仕様が、並行実行のパフォーマンスを考慮したものに変更された経緯の提案文書 - [P0254R2 Integrating `std::string_view` and `std::string`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0254r2.pdf) +- [LWG Issue 2861. `basic_string` should require that charT match `traits::char_type`](https://cplusplus.github.io/LWG/issue2861) + - C++17で、`value_type`が`traits::char_type`ではなく`charT`として定義されるようになり、「`traits::char_type`は`charT`と同じ型である」という注記が規範的要件へ格上げされた + - この修正は欠陥報告(DR)であり、C++98以降に遡及して適用される。修正前も注記で両者が同じ型であることが述べられており、`value_type`がどちらで定義されても観測できる違いはないため diff --git a/reference/string/basic_string/assign.md b/reference/string/basic_string/assign.md index 7ae5e3327b..a140311fe8 100644 --- a/reference/string/basic_string/assign.md +++ b/reference/string/basic_string/assign.md @@ -88,7 +88,9 @@ constexpr basic_string& ## 効果 - (1) : コピー代入。`str`オブジェクトと同じ文字列を構築する。 - - `assign(str, 0, npos)`と等価。 + - C++03 : `assign(str, 0, npos)`と等価 + - C++17 : `*this = str`と等価 + - アロケータの伝播(`propagate_on_container_copy_assignment`)について、コピー代入演算子と一貫した扱いとなる - (2) : ムーブ代入。`str`オブジェクトが指すデータの所有権を自身に移動する。`str`は未規定の値になる。 - (3) : `str`オブジェクトの部分文字列のコピーから構築する。`str`オブジェクトの`pos`番目から`n`文字の部分文字列がコピーされる。 - 文字列の長さ `rlen` は、`n` と `str.`[`size`](size.md)`() - pos` の小さい方である。 `n == npos` の場合は、 `str.`[`size`](size.md)`() - pos` が使用される。 @@ -226,9 +228,11 @@ s11 : Hello - [LWG ISsue 2268. Setting a default argument in the declaration of a member function `assign` of `std::basic_string`](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2268) - C++14から(3)のオーバーロードに、`n = npos`のデフォルト引数を追加。 - [P0254R2 Integrating `std::string_view` and `std::string`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0254r2.pdf) +- [LWG Issue 2579. Inconsistency wrt Allocators in `basic_string` assignment vs. `basic_string::assign`](https://cplusplus.github.io/LWG/issue2579) + - C++17で、(1)の効果を`*this = str`と等価に変更し、アロケータ伝播についてコピー代入演算子と一貫させた - [LWG Issue 2758. `std::string{}.assign("ABCDE", 0, 1)` is ambiguous](https://wg21.cmeerw.net/lwg/issue2758) - [LWG Issue 2946. LWG 2758's resolution missed further corrections](https://wg21.cmeerw.net/lwg/issue2946) - - 意図しない暗黙変換防止のために`string_view`を受けるオーバーロード(9), (10)の引数型を`const T&`に変更 + - C++20で、意図しない暗黙変換防止のために`string_view`を受けるオーバーロード(9), (10)の引数型を`const T&`に変更 - [P0980R1 Making `std::string` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0980r1.pdf) - [LWG Issue 3662 `basic_string::append/assign(NTBS, pos, n)` suboptimal](https://cplusplus.github.io/LWG/issue3662) - C++26で、NULL終端文字列の一部分を代入する(11)のオーバーロードが追加された diff --git a/reference/string/basic_string/data.md b/reference/string/basic_string/data.md index bca8e3b511..f13c3cd140 100644 --- a/reference/string/basic_string/data.md +++ b/reference/string/basic_string/data.md @@ -51,6 +51,7 @@ constexpr charT* data() noexcept; // (2) C++20 - 対象オブジェクト内に NULL 文字があった場合、C 言語の文字列表現では正しく扱うことができないので注意すること。 - (2) : - この関数を使用するユーザーは、`p +` [`size()`](size.md) (NULL終端) に格納されている値を変更してはならない + - この関数を呼び出しても、対象オブジェクトの要素への既存の参照、ポインタ、イテレータは無効にはならない ## 例 @@ -83,5 +84,7 @@ Hello, world! ## 参照 - [P0272R1 Give `std::string` a non-const `.data()` member function.](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0272r1.html) +- [LWG Issue 2760. non-`const` `basic_string::data` should not invalidate iterators](https://cplusplus.github.io/LWG/issue2760) + - C++17の策定中に、P0272R1で追加された非const版`data()`が、参照・ポインタ・イテレータを無効化しない関数の一覧に含まれていなかった記載漏れが修正された - [LWG Issue 3131. `addressof` all the things](https://wg21.cmeerw.net/lwg/issue3131) - [P0980R1 Making `std::string` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0980r1.pdf) diff --git a/reference/string/basic_string/op_at.md b/reference/string/basic_string/op_at.md index 8906c48222..b29e3473d9 100644 --- a/reference/string/basic_string/op_at.md +++ b/reference/string/basic_string/op_at.md @@ -62,6 +62,9 @@ e ``` ## 参照 +- [LWG Issue 2475. Allow overwriting of `std::basic_string` terminator with `charT()` to allow cleaner interoperation with legacy APIs](https://cplusplus.github.io/LWG/issue2475) + - C++17で、非const版(2)の`pos == size()`で返る参照に`charT()`を書き込むことが許可された(レガシーC APIとの相互運用のため) + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。`charT()`以外の値を書き込んだ場合の未定義動作は維持されており、処理系はヌル終端文字を実際に保持しているため`charT()`の書き込みは当初から問題なく動作していた。要件の緩和であり、既存プログラムの意味は変わらないため - [P0980R1 Making `std::string` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0980r1.pdf) - [P3471R4 Standard library hardening](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3471r4.html) - [P3878R1 Standard library hardening should not use the 'observe' semantic](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) diff --git a/reference/string/basic_string/shrink_to_fit.md b/reference/string/basic_string/shrink_to_fit.md index 0499b056df..7547d30566 100644 --- a/reference/string/basic_string/shrink_to_fit.md +++ b/reference/string/basic_string/shrink_to_fit.md @@ -18,7 +18,7 @@ constexpr void shrink_to_fit(); // (1) C++20 - [`capacity`](capacity.md)`()`を[`size`](size.md)`()`に縮小させるリクエストを行う。 - 実装依存の最適化を許可するために、縮小するという動作は仕様上強制されない。 - C++17 : この関数によって[`capacity()`](capacity.md)が増えることはない。 -- C++17 : [`capacity()`](capacity.md)の縮小が起こる際に、メモリの再割り当てが発生する場合がある。その際、文字列の要素に対する参照、ポインタ、およびイテレータとそれが指す要素への参照は無効となる。 +- C++17 : [`capacity()`](capacity.md)の縮小が起こる際に、メモリの再割り当てが発生する場合がある。再割り当てが発生した場合、文字列の要素を指すすべての参照・ポインタ・イテレータ、および終端イテレータ(past-the-end iterator)が無効となる。再割り当てが発生しなければ、それらは有効なままである。 ## 戻り値 @@ -89,4 +89,6 @@ void basic_string::shrink_to_fit() { - 『[Effective STL - STLを効果的に使いこなす50の鉄則](https://www.amazon.co.jp/dp/4894714108)』 第17項 余分な容量を取り除くには「swap技法」を使おう - [LWG Issue 755. `std::vector` and `std:string` lack explicit shrink-to-fit operations] - [LWG Issue 2223. `shrink_to_fit` effect on iterator validity](https://wg21.cmeerw.net/lwg/issue2223) +- [LWG Issue 2834. Resolution to LWG 2223 is missing wording about end iterators](https://cplusplus.github.io/LWG/issue2834) + - C++17で、再割り当てが発生する場合に終端イテレータ(past-the-end iterator)も無効化されることが明確化された - [P0980R1 Making `std::string` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0980r1.pdf) diff --git a/reference/system_error/error_condition.md b/reference/system_error/error_condition.md index f247e8ac9c..c44a35b8b3 100644 --- a/reference/system_error/error_condition.md +++ b/reference/system_error/error_condition.md @@ -49,6 +49,13 @@ Visual C++ 2010、GCC 4.6.1では[`generic_category()`](generic_category.md)と[ | [`make_error_condition`](make_error_condition.md) | `errc`から`error_condition`オブジェクトを生成する | C++11 | +## その他 + +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| `hash` | `error_condition`での特殊化 | C++17 | + + ## 例 ```cpp example #include @@ -102,3 +109,5 @@ Invalid argument ## 参照 +- [LWG Issue 2686. Why is `std::hash` specialized for `error_code`, but not `error_condition`?](https://cplusplus.github.io/LWG/issue2686) + - C++17で、[`error_code`](error_code.md)と同様に`std::`[`hash`](/reference/functional/hash.md)``の特殊化が``に追加され、`unordered_set`等のキーとして使用できるようになった diff --git a/reference/tuple/ignore.md b/reference/tuple/ignore.md index baf5f77dcb..f4f1992b66 100644 --- a/reference/tuple/ignore.md +++ b/reference/tuple/ignore.md @@ -99,4 +99,6 @@ int main() { ## 参照 +- [LWG Issue 2773. Making `std::ignore` `constexpr`](https://cplusplus.github.io/LWG/issue2773) + - C++17で、`ignore`が`const`から`constexpr`に変更され、定数式で使用できるようになった - [P2968R2 Make `std::ignore` a first-class object](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2968r2.html) diff --git a/reference/tuple/tuple.md b/reference/tuple/tuple.md index deb793dbb4..caecdf3c6c 100644 --- a/reference/tuple/tuple.md +++ b/reference/tuple/tuple.md @@ -17,6 +17,11 @@ namespace std { [`pair`](/reference/utility/pair.md)型は2つの型の値を保持する「組」を表現することができるが、`tuple`ではN個の型の値を扱うことができる。 +## 備考 +- C++17 : すべての要素型がトリビアルに破棄可能(`(`[`is_trivially_destructible_v`](/reference/type_traits/is_trivially_destructible.md)` && ...)`が`true`)である場合、`tuple`のデストラクタもトリビアルなデストラクタとなる + - これにより`tuple`はリテラル型となり、定数式で使用できる + + ## メンバ関数 | 名前 | 説明 | 対応バージョン | @@ -266,3 +271,6 @@ after b: i=0, d=0 ## 参照 - [タプル - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BF%E3%83%97%E3%83%AB) - [P2321R2 `zip`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2321r2.html) +- [LWG Issue 2796. `tuple` should be a literal type](https://cplusplus.github.io/LWG/issue2796) + - C++17で、全ての要素型がトリビアルに破棄可能な場合は`tuple`のデストラクタもトリビアルになることが明記され、リテラル型として定数式で使用できることが保証された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。処理系は当初からデストラクタを宣言しておらず(暗黙定義のトリビアルなデストラクタを持つ)挙動は変わらない、規格の記載漏れの補完であるため diff --git a/reference/tuple/tuple/op_assign.md b/reference/tuple/tuple/op_assign.md index 4bef2f752b..e0f86cf7fc 100644 --- a/reference/tuple/tuple/op_assign.md +++ b/reference/tuple/tuple/op_assign.md @@ -76,10 +76,9 @@ constexpr const tuple& operator=(UTuple&&) const; // (14) C++23 [プロキシ参照](/reference/iterator/indirectly_writable.md)版とは、[プロキシ参照](/reference/iterator/indirectly_writable.md)である(要素が全て[プロキシ参照](/reference/iterator/indirectly_writable.md)である)[`tuple`](../tuple.md)が持つ各要素について、その要素の参照先へ、他の[`tuple`](../tuple.md)又は[`tuple-like`](../tuple-like.md)なオブジェクトの対応する値を代入する動作を行う版である。 -## 要件 +## テンプレートパラメータ制約 `Ti`(`i`は`[0, sizeof...(Types))`を範囲とする)が以下で現れた場合、元の[`tuple`](../tuple.md)のテンプレートパラメーターパックの`i`番目とする。また、`Ui`については、パラメーターの[`tuple`](../tuple.md)についてのテンプレートパラメーターパックの`i`番目とする。 -- (1) : 全ての`i`について、[`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value == true`であること - (2) : C++23 : 全ての`i`について、[`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)` == true`であること - (3) : 全ての`i`について、[`is_move_assignable`](/reference/type_traits/is_move_assignable.md)`::value == true`であること - (4) : C++23 : 全ての`i`について、[`is_assignable_v`](/reference/type_traits/is_assignable.md)` == true`であること @@ -101,6 +100,13 @@ constexpr const tuple& operator=(UTuple&&) const; // (14) C++23 - C++23 : [`is_assignable_v`](/reference/type_traits/is_assignable.md)`(`[`std::forward`](/reference/utility/forward.md)`(u)))>` +## delete定義される条件 +- (1) : + - C++11 : すべての`i`について[`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value == true`であることが、要件として規定されていた + - C++17 : すべての`i`について[`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)``が`true`でない場合、この演算子は`delete`定義される + - コピー代入は制約(オーバーロード解決に参加しない)ではなく`delete`定義される。一方でムーブ代入(3)は制約であるため、ムーブ代入できない場合はコピー代入がオーバーロード解決の候補となりうる + + ## 例外 - (3) : 全ての`i`について、[`is_nothrow_move_assignable`](/reference/type_traits/is_nothrow_move_assignable.md)`::value == true`の場合、決して例外を投げない。 @@ -166,3 +172,8 @@ int main() ## 参照 - [P1032R1 Misc constexpr bits](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html) - [P2165R4 Compatibility between `tuple`, `pair` and *tuple-like* objects](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf) +- [LWG Issue 2729. Missing SFINAE on `std::pair::operator=`](https://cplusplus.github.io/LWG/issue2729) + - C++17で、`pair`と同様に`tuple`のコピー代入演算子(1)も要素型のコピー代入可能性を満たさない場合は`delete`定義されるよう規定され、`is_copy_assignable`等が正しい結果を返すようになった +- [LWG Issue 2958. Moves improperly defined as deleted](https://cplusplus.github.io/LWG/issue2958) + - C++20で、ムーブ代入演算子が要素型の代入不可時に`delete`定義ではなくオーバーロード解決に参加しない形へ修正され、コピー代入へのフォールバックが可能になった + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。C++17の「`delete`定義される」という文言では、暗黙`delete`(オーバーロード解決に不参加)か明示`delete`(コピー代入を隠す)かが不明確で意図どおりに実装できなかったため diff --git a/reference/tuple/tuple/op_constructor.md b/reference/tuple/tuple/op_constructor.md index 5fd0a575f3..1a75fb5800 100644 --- a/reference/tuple/tuple/op_constructor.md +++ b/reference/tuple/tuple/op_constructor.md @@ -442,7 +442,11 @@ int main() - [N3471 Constexpr Library Additions: utilities, v3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3471.html) - [N4387 Improving Pair and Tuple (Revision 3)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387) - C++17での条件付き`explicit`の導入 -- [LWG Issue 2549. Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references](https://wg21.cmeerw.net/lwg/issue2549) +- [LWG Issue 2312. `tuple`'s constructor constraints need to be phrased more precisely](https://cplusplus.github.io/LWG/issue2312) + - C++17で、`tuple`の各コンストラクタが要素数の一致等の条件を満たす場合のみオーバーロード解決に参加するよう、制約がより厳密に規定された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。処理系は当初からこの通りに振る舞っており、規格の文言が不正確だっただけであるため +- [LWG Issue 2367. `pair` and `tuple` are not correctly implemented for `is_constructible` with no args](https://cplusplus.github.io/LWG/issue2367) + - C++17で、デフォルトコンストラクタ(1)が、いずれかの要素型がデフォルト構築可能でない場合はオーバーロード解決に参加しないよう制約化された - [P1032R1 Misc constexpr bits](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html) - [P0892R2 `explicit(bool)`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0892r2.html) - C++20での`explicit(bool)`構文への対応 @@ -450,15 +454,16 @@ int main() - [`tuple-like`](/reference/tuple/tuple-like.md)なオブジェクトからの構築 - [P2255R2 A type trait to detect reference binding to temporary](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2255r2.html) - 参照型を要素に持つ場合にダングリング参照が容易に作成できていたのを不適格にする -- [LWG 3121 tuple constructor constraints for UTypes&&... overloads](https://cplusplus.github.io/LWG/issue3121) - - C++23 での (3) のコンストラクタの制約の変更(`disambiguating-constraint`等)について +- [LWG Issue 2549. Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references](https://wg21.cmeerw.net/lwg/issue2549) - [P2321R2 `zip`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2321r2.html#tuple) - すべての要素が[プロキシ参照](/reference/iterator/indirectly_writable.md)の場合、[プロキシ参照](/reference/iterator/indirectly_writable.md)として使用できるようにする -- [LWG Issue 4045. `tuple` can create dangling references from `tuple-like`](https://cplusplus.github.io/LWG/issue4045) - - C++26で、[`tuple-like`](../tuple-like.md)なオブジェクトから構築するコンストラクタ(14)について、いずれかの要素がダングリング参照を作成する場合に削除定義されることが規定された(C++23での`tuple-like`コンストラクタ導入時に欠けていた保護の追加) -- [LWG Issue 3158. `tuple(allocator_arg_t, const Alloc&)` should be conditionally `explicit`](https://cplusplus.github.io/LWG/issue3158) - - C++20で、アロケータ拡張デフォルトコンストラクタ(15)が、非アロケータ版(1)と同じ条件で`explicit`となるよう修正された - [LWG Issue 2899. `is_(nothrow_)move_constructible` and `tuple`, `optional` and `unique_ptr`](https://cplusplus.github.io/LWG/issue2899) - C++20で、ムーブコンストラクタ(5)が、いずれかの要素型がムーブ構築可能でない場合はオーバーロード解決に参加しないよう制約化された +- [LWG 3121 tuple constructor constraints for UTypes&&... overloads](https://cplusplus.github.io/LWG/issue3121) + - C++23 での (3) のコンストラクタの制約の変更(`disambiguating-constraint`等)について +- [LWG Issue 3158. `tuple(allocator_arg_t, const Alloc&)` should be conditionally `explicit`](https://cplusplus.github.io/LWG/issue3158) + - C++20で、アロケータ拡張デフォルトコンストラクタ(15)が、非アロケータ版(1)と同じ条件で`explicit`となるよう修正された - [LWG Issue 3211. `std::tuple<>` should be trivially constructible](https://cplusplus.github.io/LWG/issue3211) - C++23で、空の`tuple<>`のデフォルトコンストラクタがトリビアルであることが規定された +- [LWG Issue 4045. `tuple` can create dangling references from `tuple-like`](https://cplusplus.github.io/LWG/issue4045) + - C++26で、[`tuple-like`](../tuple-like.md)なオブジェクトから構築するコンストラクタ(14)について、いずれかの要素がダングリング参照を作成する場合に削除定義されることが規定された(C++23での`tuple-like`コンストラクタ導入時に欠けていた保護の追加) diff --git a/reference/tuple/tuple_element.md b/reference/tuple/tuple_element.md index d8f649f864..06a6c707a4 100644 --- a/reference/tuple/tuple_element.md +++ b/reference/tuple/tuple_element.md @@ -45,6 +45,10 @@ namespace std { - (6) : エイリアステンプレート版 +## 適格要件 +- (5) : `I < sizeof...(Types)`であること + + ## 非推奨の詳細 - (3), (4) : これらの部分特殊化は、型の`volatile`修飾を部分的に非推奨にすることにともなって、非推奨化される diff --git a/reference/type_traits/add_lvalue_reference.md b/reference/type_traits/add_lvalue_reference.md index 0b2f20236a..b44f0096e3 100644 --- a/reference/type_traits/add_lvalue_reference.md +++ b/reference/type_traits/add_lvalue_reference.md @@ -24,6 +24,7 @@ namespace std { - `add_lvalue_reference`は、型`T`の名前に`&`修飾を付加した型を、メンバ型`type`として定義する。 - 型`T`が何らかのオブジェクト型もしくは関数型`U`への左辺値参照型である場合は、型`U&`をメンバ型`type`として定義する。 - 型`T`が何らかのオブジェクト型もしくは関数型`U`への右辺値参照型である場合は、型`U&`をメンバ型`type`として定義する。 +- 型`T`が参照可能でない型(`void`や、CV修飾・参照修飾された関数型)である場合は、型`T`をそのままメンバ型`type`として定義する。 ## 例 @@ -58,3 +59,6 @@ int main() {} ## 参照 - [N3546 TransformationTraits Redux](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3546.pdf) - [N3655 TransformationTraits Redux, v2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3655.pdf) +- [LWG Issue 2101. Some transformation types can produce impossible types](https://cplusplus.github.io/LWG/issue2101) + - C++17で、参照可能でない型(`void`やCV修飾・参照修飾された関数型)に対して不適格な型を生成しないよう規定が整理された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。CV修飾・参照修飾された関数型に対して`void(&)() const`のような型システムに存在しない型を作ろうとする元の規定は実装不可能であり、処理系は当初から型`T`をそのまま返していたため diff --git a/reference/type_traits/add_pointer.md b/reference/type_traits/add_pointer.md index f3135a9d4c..a9e84d1974 100644 --- a/reference/type_traits/add_pointer.md +++ b/reference/type_traits/add_pointer.md @@ -21,7 +21,8 @@ namespace std { ## 効果 -`add_pointer`は、型[`remove_reference`](remove_reference.md)`::type*`を、メンバ型`type`として定義する。 +- 型`T`が参照可能な型(オブジェクト型・参照型、およびCV修飾・参照修飾のない関数型)もしくは(CV修飾されていてもよい)`void`である場合、`add_pointer`は型[`remove_reference`](remove_reference.md)`::type*`をメンバ型`type`として定義する。 +- そうでない場合(CV修飾・参照修飾された関数型)は、型`T`をそのままメンバ型`type`として定義する。 ## 例 @@ -55,3 +56,6 @@ int main() {} ## 参照 - [N3546 TransformationTraits Redux](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3546.pdf) - [N3655 TransformationTraits Redux, v2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3655.pdf) +- [LWG Issue 2101. Some transformation types can produce impossible types](https://cplusplus.github.io/LWG/issue2101) + - C++17で、CV修飾・参照修飾された関数型に対して不適格な型を生成しないよう規定が整理された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。CV修飾・参照修飾された関数型に対して`void(&)() const`のような型システムに存在しない型を作ろうとする元の規定は実装不可能であり、処理系は当初から型`T`をそのまま返していたため diff --git a/reference/type_traits/add_rvalue_reference.md b/reference/type_traits/add_rvalue_reference.md index 703bfcc91b..4ce3af0c2f 100644 --- a/reference/type_traits/add_rvalue_reference.md +++ b/reference/type_traits/add_rvalue_reference.md @@ -21,7 +21,7 @@ namespace std { ## 効果 -`add_rvalue_reference`は、オブジェクト型もしくは関数型`T`の名前に`&&`修飾を付加した型を、メンバ型`type`として定義する。そうでない場合は、型`T`をそのままメンバ型`type`として定義する。 +`add_rvalue_reference`は、参照可能な型`T`の名前に`&&`修飾を付加した型を、メンバ型`type`として定義する。型`T`が参照可能でない型(`void`や、CV修飾・参照修飾された関数型)である場合は、型`T`をそのままメンバ型`type`として定義する。 ※`T&`は`T&&`にはならず、`T&`のままとなる。 @@ -56,3 +56,6 @@ int main() {} ## 参照 - [N3546 TransformationTraits Redux](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3546.pdf) - [N3655 TransformationTraits Redux, v2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3655.pdf) +- [LWG Issue 2101. Some transformation types can produce impossible types](https://cplusplus.github.io/LWG/issue2101) + - C++17で、参照可能でない型(`void`やCV修飾・参照修飾された関数型)に対して不適格な型を生成しないよう規定が整理された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。CV修飾・参照修飾された関数型に対して`void(&)() const`のような型システムに存在しない型を作ろうとする元の規定は実装不可能であり、処理系は当初から型`T`をそのまま返していたため diff --git a/reference/type_traits/conjunction.md b/reference/type_traits/conjunction.md index 3f32e3593b..b4a330b7ea 100644 --- a/reference/type_traits/conjunction.md +++ b/reference/type_traits/conjunction.md @@ -18,7 +18,8 @@ namespace std { 複数の特性(bool値を返すメタ関数)の論理積を計算する。 ## 要件 -Traits内の全ての型は基底クラスとして使用可能で(final指定されていない)、boolに変換可能なメンバ変数valueを持つこと。 +- `Traits`内の型のうち、`Bi::value`が実体化されるものは、基底クラスとして使用可能で(`final`指定されていない)、`bool`に変換可能なメンバ変数`value`を持つこと。 + - 短絡評価によって`value`が参照されない型には、この要件は及ばない。 ## 効果 `sizeof...(Traits) == 0`ならば[`true_type`](true_type.md)から派生し @@ -90,3 +91,9 @@ Tはムーブ構築/代入どちらかが不可 - [C++17 で追加された std::conjunction/std::disjunction メタ関数 - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2017/08/13/203150) - [conjunction/disjunctionと短絡インスタンス化 - yohhoyの日記](https://yohhoy.hatenadiary.jp/entry/20171103/p1) - [Logical Operator Type Traits (revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html) +- [LWG Issue 2557. Logical operator traits are broken in the zero-argument case](https://cplusplus.github.io/LWG/issue2557) + - C++17の策定中に、引数が0個の場合(`conjunction<>`は`true_type`、`disjunction<>`は`false_type`)を正しく扱うよう文言が整理された +- [LWG Issue 2567. Specification of logical operator traits uses `BaseCharacteristic`, which is defined only for `UnaryTypeTraits` and `BinaryTypeTraits`](https://cplusplus.github.io/LWG/issue2567) + - C++17の策定中に、`conjunction`/`disjunction`/`negation`のBaseCharacteristic(派生元の基底)の規定が、どの型から派生するかを明示する形に整理された +- [LWG Issue 2569. `conjunction` and `disjunction` requirements are too strict](https://cplusplus.github.io/LWG/issue2569) + - C++17の策定中に、テンプレート引数のうち`Bi::value`が実体化されるものだけが基底クラスとして使用可能であればよい、と要件が緩和された(短絡評価される型には要件が及ばない) diff --git a/reference/type_traits/disjunction.md b/reference/type_traits/disjunction.md index 39ed7d45d6..546f3fd950 100644 --- a/reference/type_traits/disjunction.md +++ b/reference/type_traits/disjunction.md @@ -18,7 +18,8 @@ namespace std { 複数の特性(bool値を返すメタ関数)の論理和を計算する。 ## 要件 -Traits内の全ての型は基底クラスとして使用可能で(final指定されていない)、boolに変換可能なメンバ変数valueを持つこと。 +- `Traits`内の型のうち、`Bi::value`が実体化されるものは、基底クラスとして使用可能で(`final`指定されていない)、`bool`に変換可能なメンバ変数`value`を持つこと。 + - 短絡評価によって`value`が参照されない型には、この要件は及ばない。 ## 効果 `sizeof...(Traits) == 0`ならば[`false_type`](false_type.md)から派生し @@ -97,3 +98,9 @@ Tは何らかのポインタ - [C++17 で追加された std::conjunction/std::disjunction メタ関数 - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2017/08/13/203150) - [conjunction/disjunctionと短絡インスタンス化 - yohhoyの日記](https://yohhoy.hatenadiary.jp/entry/20171103/p1) - [Logical Operator Type Traits (revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html) +- [LWG Issue 2557. Logical operator traits are broken in the zero-argument case](https://cplusplus.github.io/LWG/issue2557) + - C++17の策定中に、引数が0個の場合(`conjunction<>`は`true_type`、`disjunction<>`は`false_type`)を正しく扱うよう文言が整理された +- [LWG Issue 2567. Specification of logical operator traits uses `BaseCharacteristic`, which is defined only for `UnaryTypeTraits` and `BinaryTypeTraits`](https://cplusplus.github.io/LWG/issue2567) + - C++17の策定中に、`conjunction`/`disjunction`/`negation`のBaseCharacteristic(派生元の基底)の規定が、どの型から派生するかを明示する形に整理された +- [LWG Issue 2569. `conjunction` and `disjunction` requirements are too strict](https://cplusplus.github.io/LWG/issue2569) + - C++17の策定中に、テンプレート引数のうち`Bi::value`が実体化されるものだけが基底クラスとして使用可能であればよい、と要件が緩和された(短絡評価される型には要件が及ばない) diff --git a/reference/type_traits/is_literal_type.md b/reference/type_traits/is_literal_type.md index 8edb4bec67..13b0e6c957 100644 --- a/reference/type_traits/is_literal_type.md +++ b/reference/type_traits/is_literal_type.md @@ -94,3 +94,5 @@ Clang 3.0では、上記サンプルにおける`X`型が、リテラル型と - [P0174R2 Deprecating Vestigial Library Parts in C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0174r2.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) - [LWG Issue `is_literal_type_v` should be `inline`](https://wg21.cmeerw.net/lwg/issue3042) +- [LWG Issue 2838. `is_literal_type` specification needs a little cleanup](https://cplusplus.github.io/LWG/issue2838) + - C++17で、非推奨annexへの移動時に失われていた「利用者による特殊化を禁止する(追加した場合は未定義動作)」規定が復元され、`UnaryTypeTrait`としての文言が整理された diff --git a/reference/type_traits/is_trivially_assignable.md b/reference/type_traits/is_trivially_assignable.md index b0e5010bed..d947f36e96 100644 --- a/reference/type_traits/is_trivially_assignable.md +++ b/reference/type_traits/is_trivially_assignable.md @@ -26,7 +26,12 @@ namespace std { ## 効果 `is_trivially_assignable`は、型`T`が型`U`からトリビアルに代入可能であるならば[`true_type`](true_type.md)から派生し、そうでなければ[`false_type`](false_type.md)から派生する。 -「トリビアルに代入可能」とは、ユーザー定義されない代入演算子を持っているということを意味する。 +「トリビアルに代入可能」とは、[`is_assignable`](is_assignable.md)`::value == true`であり、かつ`declval() = declval()`という代入が、トリビアルでない操作を呼び出さないことが分かっていることを意味する。 + + +## 備考 +- このトレイトの定義においては、`declval()`という関数呼び出しは、トリビアルな関数呼び出しであり、かつ[`declval`](/reference/utility/declval.md)のODR使用ではないものとみなされる。 + - [`declval`](/reference/utility/declval.md)は特殊メンバ関数ではないため、この規定がなければ、代入式は必ず「トリビアルでない操作の呼び出し」を含むことになり、このトレイトは常に`false`となってしまう。 ## 例 @@ -91,3 +96,6 @@ int main() {} ## 参照 - [P0006R0 Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0006r0.html) +- [LWG Issue 2336. `is_trivially_constructible`/`is_trivially_assignable` traits are always false](https://cplusplus.github.io/LWG/issue2336) + - C++17で、`declval()`の呼び出しをトリビアルとみなすよう規定が修正され、これらのトレイトが常に`false`となる文言上の欠陥が解消された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。文言上の欠陥の修正であり、処理系は当初から正しい結果を返していたため diff --git a/reference/type_traits/is_trivially_constructible.md b/reference/type_traits/is_trivially_constructible.md index e5e2785734..3f24f4fc9b 100644 --- a/reference/type_traits/is_trivially_constructible.md +++ b/reference/type_traits/is_trivially_constructible.md @@ -26,7 +26,12 @@ namespace std { ## 効果 `is_trivially_constructible`は、`T( Args... )`の形式のコンストラクタ呼出しがトリビアルに可能であるならば[`true_type`](true_type.md)から派生し、そうでなければ[`false_type`](false_type.md)から派生する。 -「トリビアルに構築可能」とは、ユーザー定義されないコンストラクタを持っていることを意味する。 +「トリビアルに構築可能」とは、[`is_constructible`](is_constructible.md)`::value == true`であり、かつ`is_constructible`で定義される変数定義`T t(declval()...);`が、トリビアルでない操作を呼び出さないことが分かっていることを意味する。 + + +## 備考 +- このトレイトの定義においては、`declval()`という関数呼び出しは、トリビアルな関数呼び出しであり、かつ[`declval`](/reference/utility/declval.md)のODR使用ではないものとみなされる。 + - [`declval`](/reference/utility/declval.md)は特殊メンバ関数ではないため、この規定がなければ、変数定義は必ず「トリビアルでない操作の呼び出し」を含むことになり、このトレイトは常に`false`となってしまう。 ## 例 @@ -91,3 +96,6 @@ int main() {} ## 参照 - [P0006R0 Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0006r0.html) +- [LWG Issue 2336. `is_trivially_constructible`/`is_trivially_assignable` traits are always false](https://cplusplus.github.io/LWG/issue2336) + - C++17で、`declval()`の呼び出しをトリビアルとみなすよう規定が修正され、これらのトレイトが常に`false`となる文言上の欠陥が解消された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。文言上の欠陥の修正であり、処理系は当初から正しい結果を返していたため diff --git a/reference/type_traits/is_trivially_destructible.md b/reference/type_traits/is_trivially_destructible.md index 1f4fa497e0..64c07e64b1 100644 --- a/reference/type_traits/is_trivially_destructible.md +++ b/reference/type_traits/is_trivially_destructible.md @@ -24,9 +24,9 @@ namespace std { ## 効果 -`is_trivially_destructible`は、`T`がトリビアルに破棄可能な型であるならば[`true_type`](true_type.md)から派生し、そうでなければ[`false_type`](false_type.md)から派生する。 - -「トリビアルに破棄可能」とは、ユーザー定義されないデストラクタを持っているということを意味する。 +- `is_trivially_destructible`は、`T`がトリビアルに破棄可能な型であるならば[`true_type`](true_type.md)から派生し、そうでなければ[`false_type`](false_type.md)から派生する。 +- 「トリビアルに破棄可能」とは、[`is_destructible`](is_destructible.md)`::value == true`であり、かつ[`remove_all_extents`](remove_all_extents.md)`::type`が非クラス型であるか、トリビアルなデストラクタを持つクラス型であることを意味する。 + - `int`のような組み込み型や、それらの配列も、トリビアルに破棄可能である。 ## 例 @@ -157,3 +157,5 @@ destruct - [An Example that Omits Destructor Calls For Types with Trivial Destructors](http://www.boost.org/doc/libs/1_65_1/libs/type_traits/doc/html/boost_typetraits/examples/destruct.html) - デストラクタを呼び出す必要のない型の配列に対して、デストラクタを呼び出すループを省略する最適化の例 - [Multiple destructors with C++ concepts - Sandor Dargo's Blog](https://www.sandordargo.com/blog/2021/06/16/multiple-destructors-with-cpp-concepts) +- [LWG Issue 2972. What is `is_trivially_destructible_v`?](https://cplusplus.github.io/LWG/issue2972) + - C++20で、「`remove_all_extents_t`が非クラス型か、トリビアルなデストラクタを持つクラス型である」という条件へ整理され、`int`のような組み込み型でも正しく`true`となることが明確化された。この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される diff --git a/reference/type_traits/negation.md b/reference/type_traits/negation.md index 1dd3a7319c..fe7679d7ab 100644 --- a/reference/type_traits/negation.md +++ b/reference/type_traits/negation.md @@ -82,3 +82,5 @@ struct negation : bool_constant {}; ## 参照 - [Logical Operator Type Traits (revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html) +- [LWG Issue 2567. Specification of logical operator traits uses `BaseCharacteristic`, which is defined only for `UnaryTypeTraits` and `BinaryTypeTraits`](https://cplusplus.github.io/LWG/issue2567) + - C++17の策定中に、`negation`の基底が`bool_constant`であると規定され、`bool()`による明示的変換が加えられた diff --git a/reference/type_traits/result_of.md b/reference/type_traits/result_of.md index 3a17638757..5751f8d9a9 100644 --- a/reference/type_traits/result_of.md +++ b/reference/type_traits/result_of.md @@ -162,3 +162,5 @@ Hello World - [N3655 TransformationTraits Redux, v2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3655.pdf) - [P0604R0 Resolving GB 55, US 84, US 85, US 86](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html) - [P0619R4 Reviewing deprecated facilities of C++17 for C++20](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html) +- [LWG Issue 2940. `result_of` specification also needs a little cleanup](https://cplusplus.github.io/LWG/issue2940) + - C++20で、非推奨annexへの移動時に失われていた「利用者による特殊化を禁止する(追加した場合は未定義動作)」規定が復元された。この修正は欠陥報告(DR)であり、C++17にも遡及して適用される diff --git a/reference/unordered_map/unordered_map/merge.md b/reference/unordered_map/unordered_map/merge.md index 548e3b7c41..030fd1a162 100644 --- a/reference/unordered_map/unordered_map/merge.md +++ b/reference/unordered_map/unordered_map/merge.md @@ -45,6 +45,10 @@ constexpr void merge(unordered_multimap&& source); // 平均的なケースでは `O(N)`、最悪ケースでは `O(N*size()+N)`、ただし `N` は `source.size()` である。 +## 例外 +[`max_load_factor()`](max_load_factor.md)の不変条件を維持するために再ハッシュが必要となる場合があり、その際のメモリ確保により例外が送出される可能性がある。また、ハッシュ関数やキー等価述語が例外を送出する場合もある。 + + ## 備考 `source` の転送された要素へのポインタおよび参照は、それらと同じ要素を参照するが、`*this` のメンバとして参照する。また、転送された要素を参照する反復子と`*this`を参照するすべての反復子は無効になるが、 `source` に残っている要素への反復子は有効なままになる。 @@ -104,4 +108,7 @@ m2 : ## 参照 - [Splicing Maps and Sets(Revision 5)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf) +- [LWG Issue 2977. `unordered_meow::merge()` has incorrect Throws: clause](https://cplusplus.github.io/LWG/issue2977) + - C++20で、「ハッシュ関数とキー等価述語以外は例外を投げない」という誤った例外指定が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。`max_load_factor`の不変条件を維持するための再ハッシュでメモリ確保が発生しうるため、元の「投げない」保証は実装不可能だったため - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/unordered_map/unordered_map/op_at.md b/reference/unordered_map/unordered_map/op_at.md index 84b0cbca19..d5b2072b5d 100644 --- a/reference/unordered_map/unordered_map/op_at.md +++ b/reference/unordered_map/unordered_map/op_at.md @@ -27,6 +27,18 @@ constexpr T& operator[](K&& k); // (3) C++26 - (3) : `key_compare::is_transparent` が妥当な式であること +## 効果 +- (1) : + - C++11 : `x`と等価なキーを持つ要素が存在しない場合、`value_type(x, T())`を挿入する + - C++17 : [`try_emplace`](try_emplace.md)`(x).first->second`と等価 +- (2) : + - C++11 : `x`と等価なキーを持つ要素が存在しない場合、`value_type(`[`move`](/reference/utility/move.md)`(x), T())`を挿入する + - C++17 : [`try_emplace`](try_emplace.md)`(`[`move`](/reference/utility/move.md)`(x)).first->second`と等価 +- (1), (2) : + - C++17 : 要素(`value_type`)はアロケータを通じて一体で構築される +- (3) : `try_emplace(`[`forward`](/reference/utility/forward.md)`(k)).first->second`と等価 + + ## 戻り値 キー`x`に対応する値を返す。対応する要素が存在しない場合は、要素を値初期化して参照を返す。 @@ -106,3 +118,6 @@ size=2 - [P2363R5 Extending associative containers with the remaining heterogeneous overloads](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html) - C++26で`template `のバージョンが追加された - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) +- [LWG Issue 2469. Wrong specification of Requires clause of `operator[]` for `map` and `unordered_map`](https://cplusplus.github.io/LWG/issue2469) + - C++17で、(1), (2)の効果が[`try_emplace`](try_emplace.md)を用いて規定され、要素を`value_type`として一体で構築する矛盾のない要件へ整理された + - 元の要件は`key_type`と`mapped_type`を別々に構築することを求めており、要素が`value_type`として一体で構築されるという規定と矛盾していた。ただし修正後の文言が用いる[`try_emplace`](try_emplace.md)はC++17で追加されたメンバ関数であるため、この規定自体をそれ以前のバージョンへ遡及して適用することはできない diff --git a/reference/unordered_map/unordered_multimap/merge.md b/reference/unordered_map/unordered_multimap/merge.md index 2c39db2f93..b88123885b 100644 --- a/reference/unordered_map/unordered_multimap/merge.md +++ b/reference/unordered_map/unordered_multimap/merge.md @@ -44,6 +44,10 @@ constexpr void merge(unordered_multimap&& source); // 平均的なケースでは `O(N)`、最悪ケースでは `O(N*size()+N)`、ただし `N` は `source.size()` である。 +## 例外 +[`max_load_factor()`](max_load_factor.md)の不変条件を維持するために再ハッシュが必要となる場合があり、その際のメモリ確保により例外が送出される可能性がある。また、ハッシュ関数やキー等価述語が例外を送出する場合もある。 + + ## 備考 `source` の転送された要素へのポインタおよび参照は、それらと同じ要素を参照するが、`*this` のメンバとして参照する。また、転送された要素を参照する反復子と`*this`を参照するすべての反復子は無効になるが、 `source` に残っている要素への反復子は有効なままになる。 @@ -103,4 +107,7 @@ m2 : ## 参照 - [Splicing Maps and Sets(Revision 5)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf) +- [LWG Issue 2977. `unordered_meow::merge()` has incorrect Throws: clause](https://cplusplus.github.io/LWG/issue2977) + - C++20で、「ハッシュ関数とキー等価述語以外は例外を投げない」という誤った例外指定が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。`max_load_factor`の不変条件を維持するための再ハッシュでメモリ確保が発生しうるため、元の「投げない」保証は実装不可能だったため - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/unordered_set/unordered_multiset/merge.md b/reference/unordered_set/unordered_multiset/merge.md index 4951fca192..bfccf9b3fd 100644 --- a/reference/unordered_set/unordered_multiset/merge.md +++ b/reference/unordered_set/unordered_multiset/merge.md @@ -44,6 +44,10 @@ constexpr void merge(unordered_multiset&& source); // (4 平均的なケースでは `O(N)`、最悪ケースでは `O(N*size()+N)`、ただし `N` は `source.size()` である。 +## 例外 +[`max_load_factor()`](max_load_factor.md)の不変条件を維持するために再ハッシュが必要となる場合があり、その際のメモリ確保により例外が送出される可能性がある。また、ハッシュ関数やキー等価述語が例外を送出する場合もある。 + + ## 備考 `source` の転送された要素へのポインタおよび参照は、それらと同じ要素を参照するが、`*this` のメンバとして参照する。また、転送された要素を参照する反復子と`*this`を参照するすべての反復子は無効になるが、 `source` に残っている要素への反復子は有効なままになる。 @@ -96,4 +100,7 @@ s2 = { 10, 10, 20, 30 } ## 参照 - [Splicing Maps and Sets(Revision 5)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf) +- [LWG Issue 2977. `unordered_meow::merge()` has incorrect Throws: clause](https://cplusplus.github.io/LWG/issue2977) + - C++20で、「ハッシュ関数とキー等価述語以外は例外を投げない」という誤った例外指定が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。`max_load_factor`の不変条件を維持するための再ハッシュでメモリ確保が発生しうるため、元の「投げない」保証は実装不可能だったため - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/unordered_set/unordered_set/merge.md b/reference/unordered_set/unordered_set/merge.md index f0ae2ae30e..f8b136805e 100644 --- a/reference/unordered_set/unordered_set/merge.md +++ b/reference/unordered_set/unordered_set/merge.md @@ -45,6 +45,10 @@ constexpr void merge(unordered_multiset&& source); // (4 平均的なケースでは `O(N)`、最悪ケースでは `O(N*size()+N)`、ただし `N` は `source.size()` である。 +## 例外 +[`max_load_factor()`](max_load_factor.md)の不変条件を維持するために再ハッシュが必要となる場合があり、その際のメモリ確保により例外が送出される可能性がある。また、ハッシュ関数やキー等価述語が例外を送出する場合もある。 + + ## 備考 `source` の転送された要素へのポインタおよび参照は、それらと同じ要素を参照するが、`*this` のメンバとして参照する。また、転送された要素を参照する反復子と`*this`を参照するすべての反復子は無効になるが、 `source` に残っている要素への反復子は有効なままになる。 @@ -97,4 +101,7 @@ s2 = { 20, 30, 10 } ## 参照 - [Splicing Maps and Sets(Revision 5)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf) +- [LWG Issue 2977. `unordered_meow::merge()` has incorrect Throws: clause](https://cplusplus.github.io/LWG/issue2977) + - C++20で、「ハッシュ関数とキー等価述語以外は例外を投げない」という誤った例外指定が削除された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。`max_load_factor`の不変条件を維持するための再ハッシュでメモリ確保が発生しうるため、元の「投げない」保証は実装不可能だったため - [P3372R3 constexpr containers and adaptors](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) diff --git a/reference/utility/pair.md b/reference/utility/pair.md index 833be72ac8..f7788b6fdf 100644 --- a/reference/utility/pair.md +++ b/reference/utility/pair.md @@ -18,6 +18,11 @@ namespace std { - C++20 : `T1`と`T2`がどちらも構造的型である場合、この型は構造的型となる +## 備考 +- C++17 : 両方の要素型がトリビアルに破棄可能([`is_trivially_destructible_v`](/reference/type_traits/is_trivially_destructible.md)` &&` [`is_trivially_destructible_v`](/reference/type_traits/is_trivially_destructible.md)``が`true`)である場合、`pair`のデストラクタもトリビアルなデストラクタとなる + - これにより`pair`はリテラル型となり、定数式で使用できる + + ## メンバ変数 | 名前 | 説明 | 対応バージョン | @@ -261,3 +266,6 @@ after b: i=0, d=0 ## 参照 - [タプル - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BF%E3%83%97%E3%83%AB) - [P2321R2 zip](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2321r2.html) +- [LWG Issue 2796. `tuple` should be a literal type](https://cplusplus.github.io/LWG/issue2796) + - C++17で、両方の要素型がトリビアルに破棄可能な場合は`pair`のデストラクタもトリビアルになることが明記され、リテラル型として定数式で使用できることが保証された + - この修正は欠陥報告(DR)であり、C++98以降に遡及して適用される。処理系は当初からデストラクタを宣言しておらず(暗黙定義のトリビアルなデストラクタを持つ)挙動は変わらない、規格の記載漏れの補完であるため diff --git a/reference/utility/pair/op_assign.md b/reference/utility/pair/op_assign.md index fbd0c52fe7..14e6d5ab7a 100644 --- a/reference/utility/pair/op_assign.md +++ b/reference/utility/pair/op_assign.md @@ -53,8 +53,7 @@ template [プロキシ参照](/reference/iterator/indirectly_writable.md)版とは、[プロキシ参照](/reference/iterator/indirectly_writable.md)である(要素がどちらも[プロキシ参照](/reference/iterator/indirectly_writable.md)である)[`pair`](../pair.md)が持つ各要素について、その要素の参照先へ、他の[`pair`](../pair.md)又は[`pair-like`](/reference/tuple/pair-like.md)なオブジェクトの対応する値を代入する動作を行う版である。 -## 要件 -- (1) : [`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value &&` [`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value`であること +## テンプレートパラメータ制約 - (2) : C++23 : [`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)` &&` [`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)``であること - (3) : [`is_assignable`](/reference/type_traits/is_assignable.md)`::value &&` [`is_assignable`](/reference/type_traits/is_assignable.md)`::value`であること - (4) : C++23 : [`is_assignable_v`](/reference/type_traits/is_assignable.md)` &&` [`is_assignable_v`](/reference/type_traits/is_assignable.md)``であること @@ -74,6 +73,13 @@ template - C++23 : [`is_assignable_v`](/reference/type_traits/is_assignable.md)`(`[`std::forward`](/reference/utility/forward.md)`

(p)))>` +## delete定義される条件 +- (1) : + - C++11 : [`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value &&` [`is_copy_assignable`](/reference/type_traits/is_copy_assignable.md)`::value`であることが、要件として規定されていた + - C++17 : [`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)` &&` [`is_copy_assignable_v`](/reference/type_traits/is_copy_assignable.md)``が`true`でない場合、この演算子は`delete`定義される + - コピー代入は制約(オーバーロード解決に参加しない)ではなく`delete`定義される。一方でムーブ代入(5)は制約であるため、ムーブ代入できない場合はコピー代入がオーバーロード解決の候補となりうる + + ## 効果 - (1), (2), (3), (4) : `p.first`を`this->first`に、`p.second`を`this->second`にコピー代入する - (5), (6), (7), (8) : `p.first`を`this->first`に、`p.second`を`this->second`にムーブ代入する @@ -157,4 +163,9 @@ p4 : (1,abc) - (1), (3)はそれより前から実装されている。 ## 参照 +- [LWG Issue 2729. Missing SFINAE on `std::pair::operator=`](https://cplusplus.github.io/LWG/issue2729) + - C++17で、コピー代入演算子(1)が要素型のコピー代入可能性を満たさない場合は`delete`定義されるよう規定され、`is_copy_assignable`等が正しい結果を返すようになった - [P1032R1 Misc constexpr bits](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html) +- [LWG Issue 2958. Moves improperly defined as deleted](https://cplusplus.github.io/LWG/issue2958) + - C++20で、ムーブ代入演算子が要素型の代入不可時に`delete`定義ではなくオーバーロード解決に参加しない形へ修正され、コピー代入へのフォールバックが可能になった + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。C++17の「`delete`定義される」という文言では、暗黙`delete`(オーバーロード解決に不参加)か明示`delete`(コピー代入を隠す)かが不明確で意図どおりに実装できなかったため diff --git a/reference/utility/pair/op_constructor.md b/reference/utility/pair/op_constructor.md index 5b7c28c1a8..afe1b8c322 100644 --- a/reference/utility/pair/op_constructor.md +++ b/reference/utility/pair/op_constructor.md @@ -293,6 +293,8 @@ p8 : (X(1 2 3),Y(4 5)) - [N3471 Constexpr Library Additions: utilities, v3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3471.html) - [N4387 Improving Pair and Tuple (Revision 3)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387) - C++17での条件付き`explicit`の導入 +- [LWG Issue 2367. `pair` and `tuple` are not correctly implemented for `is_constructible` with no args](https://cplusplus.github.io/LWG/issue2367) + - C++17で、デフォルトコンストラクタ(1)が、いずれかの要素型がデフォルト構築可能でない場合はオーバーロード解決に参加しないよう制約化された - [P1032R1 Misc constexpr bits](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html) - [P0892R2 `explicit(bool)`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0892r2.html) - C++20での`explicit(bool)`構文への対応 diff --git a/reference/utility/pair/tuple_element.md b/reference/utility/pair/tuple_element.md index f271b8d60f..09e56fb065 100644 --- a/reference/utility/pair/tuple_element.md +++ b/reference/utility/pair/tuple_element.md @@ -27,6 +27,10 @@ namespace std { ``ヘッダでは、[`pair`](../pair.md)に関する特殊化を定義する。 +## 適格要件 +- `I < 2`であること。そうでない場合、プログラムは不適格となる + + ## 例 ```cpp example #include @@ -63,3 +67,6 @@ int main() ## 参照 - [`tuple_element - `](/reference/tuple/tuple_element.md) +- [LWG Issue 2974. Diagnose out of bounds `tuple_element`/`variant_alternative`](https://cplusplus.github.io/LWG/issue2974) + - C++20で、`I < 2`を満たさない範囲外のインデックス指定時にプログラムが不適格(診断必須)となることが規定された + - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。範囲外のインデックス指定は主テンプレート(不完全型)に解決されるだけで診断が保証されておらず、妥当なプログラムが旧挙動に依存することはないため diff --git a/reference/utility/piecewise_construct_t.md b/reference/utility/piecewise_construct_t.md index 8e64d9a56d..2724d117ea 100644 --- a/reference/utility/piecewise_construct_t.md +++ b/reference/utility/piecewise_construct_t.md @@ -67,3 +67,5 @@ int main() ## 参照 - [N3059 Proposal to Simplify `pair` (rev 5.2)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3059.pdf) - [N3059 - togetter](https://togetter.com/li/17236) +- [LWG Issue 2510. Tag types should not be `DefaultConstructible`](https://cplusplus.github.io/LWG/issue2510) + - C++17で、`{}`による暗黙構築を防ぐため、明示的なデフォルトコンストラクタ(`explicit piecewise_construct_t() = default;`)が追加された diff --git a/reference/variant/variant.md b/reference/variant/variant.md index 35f4856e2b..176fe1f6e5 100644 --- a/reference/variant/variant.md +++ b/reference/variant/variant.md @@ -142,14 +142,6 @@ std::visit([](auto& x) { | `template struct hash>;` | `hash`クラスの`variant`に対する特殊化 | C++17 | -## アロケータインタフェース - -| 名前 | 説明 | 対応バージョン | -|------------------------------------------------|----------------------------------------|-------| -| `template struct uses_allocator;` | `uses_allocator`クラスの先行宣言 | C++17 | -| `template `
`struct uses_allocator, Alloc>;` | `uses_allocator`クラスの`variant`に対する特殊化 | C++17 | - - ## 例 ```cpp example #include @@ -219,4 +211,6 @@ Hello - [P0110R0 Implementing the strong guarantee for `variant<>` assignment](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0110r0.html) - [P0308R0 Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html) - [P0510R0 Disallowing references, incomplete types, arrays, and empty variants](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0510r0.html) +- [LWG Issue 2901. `variant`s cannot properly support allocators](https://cplusplus.github.io/LWG/issue2901) + - C++17の策定中に、アロケータ対応のコンストラクタと`uses_allocator`の特殊化が削除された(公開されたC++17にはこれらは存在しない)。`variant`は後続の値の代入で構築時のアロケータが失われるため、適切なアロケータ対応ができないという理由による - [LWG Issue 3196. `std::optional` is ill-formed is `T` is an array](https://wg21.cmeerw.net/lwg/issue3196) diff --git a/reference/variant/variant/emplace.md b/reference/variant/variant/emplace.md index d60c9570e9..672be3abea 100644 --- a/reference/variant/variant/emplace.md +++ b/reference/variant/variant/emplace.md @@ -69,10 +69,12 @@ constexpr variant_alternative_t>& - (3) : - 値を保持している場合、破棄する - - `Types...`の`I`番目の型を`Ti`として、`Ti`型オブジェクトをコンストラクタ引数[`std::forward`](/reference/utility/forward.md)`(args)...`で構築して保持する + - `Types...`の`I`番目の型を`Ti`として、`Ti`型オブジェクトをコンストラクタ引数[`std::forward`](/reference/utility/forward.md)`(args)...`から構築して保持する - (4) : - 値を保持している場合、破棄する - - `Types...`の`I`番目の型を`Ti`として、`Ti`型オブジェクトをコンストラクタ引数`il`と[`std::forward`](/reference/utility/forward.md)`(args)...`で構築して保持する + - `Types...`の`I`番目の型を`Ti`として、`Ti`型オブジェクトをコンストラクタ引数`il`と[`std::forward`](/reference/utility/forward.md)`(args)...`から構築して保持する + +いずれのオーバーロードでも、値の構築は丸カッコによる直接初期化 (direct-non-list-initialization) で行われる。波カッコによる初期化ではないため、要素型が[`std::initializer_list`](/reference/initializer_list/initializer_list.md)を受け取るコンストラクタを持つ場合でも、(1), (3)ではそのコンストラクタは選ばれない。 ## 戻り値 @@ -190,3 +192,5 @@ int main() - [P2231R1 Missing `constexpr` in `std::optional` and `std::variant`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2231r1.html) - [LWG Issue 2746. Inconsistency between requirements for `emplace` between `optional` and `variant`](https://cplusplus.github.io/LWG/issue2746) - C++26で、`emplace`の制約が`Requires`(ハードエラー)から`Constraints`(SFINAE)に統一された(cpprefjpでは「テンプレートパラメータ制約」として記載済み) +- [LWG Issue 2903. The form of initialization for the emplace-constructors is not specified](https://cplusplus.github.io/LWG/issue2903) + - C++17の策定中に、`variant`の`emplace`が`optional`と同様に「direct-non-list-initialization(丸カッコによる直接初期化)」で値を初期化することが明確化された diff --git a/reference/variant/variant/op_assign.md b/reference/variant/variant/op_assign.md index 36433b1f54..35075e509d 100644 --- a/reference/variant/variant/op_assign.md +++ b/reference/variant/variant/op_assign.md @@ -197,3 +197,5 @@ int main() - [P0608R3 A sane variant converting constructor](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r3.html) - [P0602R4 `variant` and `optional` should propagate copy/move triviality](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0602r4.html) - [P2231R1 Missing `constexpr` in `std::optional` and `std::variant`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2231r1.html) +- [LWG Issue 2904. Make `variant` move-assignment more exception safe](https://cplusplus.github.io/LWG/issue2904) + - C++17の策定中に、コピー代入と変換代入において`is_nothrow`系の判定に基づいて`emplace`する形へ整理され、`valueless_by_exception`状態になる可能性が減った(ムーブ代入は無条件に`emplace`する) diff --git a/reference/variant/variant/op_constructor.md b/reference/variant/variant/op_constructor.md index 4a1a455b3b..1458c9daaf 100644 --- a/reference/variant/variant/op_constructor.md +++ b/reference/variant/variant/op_constructor.md @@ -53,8 +53,6 @@ constexpr explicit variant(in_place_index_t, - 候補型`Types...`のi番目の型を`Ti`とする - (1) : - [`is_default_constructible_v`](/reference/type_traits/is_default_constructible.md)``であること -- (2) : - - 全ての型`Ti`について、[`is_copy_constructible_v`](/reference/type_traits/is_copy_constructible.md)``が`true`であること - (3) : - 全ての型`Ti`について、[`is_move_constructible_v`](/reference/type_traits/is_move_constructible.md)``が`true`であること - (4) : @@ -133,6 +131,11 @@ constexpr explicit variant(in_place_index_t, - 型`Ti`の選択されたコンストラクタが任意の例外を送出する可能性がある +## delete定義される条件 +- (2) : いずれかの型`Ti`について、[`is_copy_constructible_v`](/reference/type_traits/is_copy_constructible.md)``が`false`である場合、このコンストラクタは`delete`定義される + - オーバーロード解決から除外される(SFINAE)のではなく`delete`定義されるため、コピー構築できない`variant`をコピーしようとすると「削除された関数の呼び出し」として診断される + + ## トリビアルに定義される条件 - (2) : 全ての`Ti`型について、[`is_trivially_copy_constructible_v`](/reference/type_traits/is_trivially_copy_constructible.md)``が`true`であること - (3) : 全ての`Ti`型について、[`is_trivially_move_constructible_v`](/reference/type_traits/is_trivially_move_constructible.md)``が`true`であること @@ -370,6 +373,9 @@ int main() - [P0777R1 Treating Unnecessary `decay`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0777r1.pdf) - C++20からテンプレートパラメータ制約の`decay_t`を`remove_cvref_t`へ変更。 - [LWG Issue 2991. `variant` copy constructor missing `noexcept(see below)`](https://cplusplus.github.io/LWG/issue2991) - - コピーコンストラクタ(2)に`noexcept(see below)`が追加され、その例外指定が全ての`Ti`についての`is_nothrow_copy_constructible_v`を論理積したものと等価であることが規定された。ムーブコンストラクタと異なりコピー側で指定が欠落していた欠陥の修正であり、この仕様はC++26で規定されたが主要な実装は早期に対応している + - C++26で、コピーコンストラクタ(2)に`noexcept(see below)`が追加され、その例外指定が全ての`Ti`についての`is_nothrow_copy_constructible_v`を論理積したものと等価であることが規定された。ムーブコンストラクタと異なりコピー側で指定が欠落していた欠陥の修正であるため、主要な実装は早期に対応している +- [LWG Issue 3024. `variant`'s copies must be deleted instead of disabled via SFINAE](https://cplusplus.github.io/LWG/issue3024) + - C++20で、コピーコンストラクタ・コピー代入演算子は、いずれかの要素型がコピー構築/コピー代入できない場合にSFINAEで除外するのではなく`delete`定義されるよう変更された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。コピーコンストラクタやコピー代入演算子をオーバーロード解決から除外する言語機構は存在せず元の規定は実装不可能であり、処理系は当初から`delete`定義していたため - [LWG Issue 4460. Missing _Throws_: for last `variant` constructor](https://cplusplus.github.io/LWG/issue4460) - - `in_place_index_t`と`initializer_list`をとる(8)のコンストラクタに、他のコンストラクタと同様に「格納する値の初期化で送出された例外を送出する」旨のThrows節が規格に追加された(規格の記載漏れの修正) + - C++26で、`in_place_index_t`と`initializer_list`をとる(8)のコンストラクタに、他のコンストラクタと同様に「格納する値の初期化で送出された例外を送出する」旨のThrows節が規格に追加された(規格の記載漏れの修正) diff --git a/reference/variant/variant/swap.md b/reference/variant/variant/swap.md index 6583c41e8e..19a8a1ada7 100644 --- a/reference/variant/variant/swap.md +++ b/reference/variant/variant/swap.md @@ -14,8 +14,12 @@ constexpr void swap(variant& rhs) noexcept(see below); // C++23 他の`variant`オブジェクトとデータを入れ替える。 -## テンプレートパラメータ制約 -- `Types...`に含まれる全ての型`Ti`について、[`is_swappable_v`](/reference/type_traits/is_swappable.md)``が`true`、かつ[`is_move_constructible_v`](/reference/type_traits/is_move_constructible.md)``が`true`であること +## 適格要件 +- `Types...`に含まれる全ての型`Ti`について、[`is_move_constructible_v`](/reference/type_traits/is_move_constructible.md)``が`true`であること + + +## 事前条件 +- `Types...`に含まれる全ての型`Ti`が、交換可能(Cpp17Swappable)の要件を満たすこと ## 効果 @@ -73,3 +77,5 @@ int main() ## 参照 - [P2231R1 Missing `constexpr` in `std::optional` and `std::variant`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2231r1.html) +- [LWG Issue 2749. swappable traits for `variant`s](https://cplusplus.github.io/LWG/issue2749) + - C++17の策定中に、メンバ`swap`の要件が「各代替型がムーブ構築可能かつ交換可能」に整理された(ムーブ代入可能は不要)。またメンバ`swap`はオーバーロード解決に参加しない制約(SFINAE)ではなく要件として規定される(SFINAE制約は非メンバ`swap`側にある) diff --git a/reference/variant/variant_alternative.md b/reference/variant/variant_alternative.md index 916b8a94f5..66404533e1 100644 --- a/reference/variant/variant_alternative.md +++ b/reference/variant/variant_alternative.md @@ -41,7 +41,7 @@ namespace std { - (6) : 修飾なし[`std::variant`](variant.md)型の候補型のうち、i番目の型を取得する -## 要件 +## 適格要件 - `I < sizeof...(Types)`であること。そうでない場合、プログラムは不適格となる @@ -133,3 +133,6 @@ int main() ## 参照 - [P1831R1 Deprecating `volatile`: library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1831r1.html) +- [LWG Issue 2974. Diagnose out of bounds `tuple_element`/`variant_alternative`](https://cplusplus.github.io/LWG/issue2974) + - C++20で、`I < sizeof...(Types)`を満たさない範囲外のインデックス指定時にプログラムが不適格(診断必須)となることが規定された + - この修正は欠陥報告(DR)であり、C++17に遡及して適用される。範囲外のインデックス指定は元は要件違反であり動作は未定義だったため、妥当なプログラムが旧挙動に依存することはない diff --git a/reference/vector/vector/erase.md b/reference/vector/vector/erase.md index 2b7cacbbe5..cb1c6f898b 100644 --- a/reference/vector/vector/erase.md +++ b/reference/vector/vector/erase.md @@ -36,11 +36,12 @@ constexpr iterator erase(const_iterator first, ## 計算量 -削除される要素の数と同じ回数の`T`のデストラクタが実行される。さらに、削除された要素以降の要素の数と同じ回数の`T`のムーブ代入演算子が呼ばれる。 +削除される要素の数と同じ回数の`T`のデストラクタが実行される。さらに、削除された要素以降の要素の数と同じ回数の`T`の代入演算子が呼ばれる。 -## 備考 -コピーコンストラクタ、ムーブコンストラクタ、代入演算子、ムーブ代入演算子が例外を投げる場合を除いて、この関数は例外を投げない。 +## 例外 +`T`の代入演算子(ムーブ代入演算子を含む)が例外を投げる場合を除いて、この関数は例外を投げない。この関数はメモリの確保・解放や要素の構築を行わないため、コンストラクタは呼ばれない。 + ## 例 ### 基本的な使い方 (C++11) @@ -139,4 +140,7 @@ int main() ## 参照 - [N2350 Container insert/erase and iterator constness (Revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf) +- [LWG Issue 2853. Possible inconsistency in specification of erase in [vector.modifiers]](https://cplusplus.github.io/LWG/issue2853) + - C++17で、例外指定からコンストラクタへの言及が削除され、`MoveAssignable`要件と整合するよう整理された + - この修正は欠陥報告(DR)であり、C++98以降に遡及して適用される。効果の規定により`erase`ではメモリの再確保が起こり得ずコンストラクタは呼ばれないため、元の例外指定は矛盾していただけで処理系の挙動は変わらないため - [P1004R2 Making `std::vector` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1004r2.pdf) diff --git a/reference/vector/vector/shrink_to_fit.md b/reference/vector/vector/shrink_to_fit.md index 8224094cfd..37b6807cdb 100644 --- a/reference/vector/vector/shrink_to_fit.md +++ b/reference/vector/vector/shrink_to_fit.md @@ -22,7 +22,7 @@ constexpr void shrink_to_fit(); // (1) C++20 - [`capacity()`](capacity.md)を[`size()`](size.md)に縮小させるというリクエストを行う。 - 実装依存の最適化を許可するために、縮小するという動作は仕様上強制されない。 - C++17 : この関数によって[`capacity()`](capacity.md)が増えることはない。 -- C++17 : [`capacity()`](capacity.md)の縮小が起こる際に、メモリの再割り当てが発生する場合がある。その際、コンテナの要素に対する参照、ポインタ、およびイテレータとそれが指す要素への参照は無効となる。 +- C++17 : [`capacity()`](capacity.md)の縮小が起こる際に、メモリの再割り当てが発生する場合がある。再割り当てが発生した場合、シーケンスの要素を指すすべての参照・ポインタ・イテレータ、および終端イテレータ(past-the-end iterator)が無効となる。再割り当てが発生しなければ、それらは有効なままである。 - C++14 : コピー挿入可能でない型`T`のムーブコンストラクタによる例外を除き、例外が送出された場合この関数は何もしない。 @@ -82,4 +82,6 @@ int main() - [LWG Issue 755. `std::vector` and `std:string` lack explicit shrink-to-fit operations](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#755) - [LWG Issue 2033. Preconditions of `reserve`, `shrink_to_fit`, and `resize` functions](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2033) - [LWG Issue 2223. `shrink_to_fit` effect on iterator validity](https://wg21.cmeerw.net/lwg/issue2223) +- [LWG Issue 2834. Resolution to LWG 2223 is missing wording about end iterators](https://cplusplus.github.io/LWG/issue2834) + - C++17で、再割り当てが発生する場合に終端イテレータ(past-the-end iterator)も無効化されることが明確化された - [P1004R2 Making `std::vector` constexpr](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1004r2.pdf) diff --git a/working_style.md b/working_style.md index bb37c58ad3..cdabef7419 100644 --- a/working_style.md +++ b/working_style.md @@ -162,6 +162,7 @@ C++11以降対応については対応バージョンを明記します。バー | virtual base class | 仮想基底クラス | | weak ordering | 弱順序 | | well-formed | 適格 | +| well-defined behavior | 定義された動作 ("well-defined" と英語のまま書かない) | | eligible | 資格のある | | synchronizes with | に対して同期する ("と同期する" だと対称関係に見えるため) | | happens before | よりも前に発生する |