std::ranges::end
| ヘッダ <ranges> で定義 |
||
| ヘッダ <iterator> で定義 |
||
| inline namespace /* 未指定 */ { inline constexpr /* 指定なし */ end = /* 指定なし */; |
(C++20以降) (カスタマイズポイントオブジェクト) |
|
| 呼び出しシグネチャ |
||
| template< class T > requires /* 以下を参照 */ |
(C++20以降) | |
範囲の終端を示すセンチネルを返します。
引数が左辺値であるか、または ranges::enable_borrowed_range<std::remove_cv_t<T>> が true である場合、ranges::end の呼び出しは 式等価です。
- t + std::extent_v<T> (
tが既知の境界を持つ配列型の場合)。- もし std::remove_all_extents_t<std::remove_reference_t<T>> が不完全型である場合、
ranges::endの呼び出しは不正形式であり、診断は不要です。
- もし std::remove_all_extents_t<std::remove_reference_t<T>> が不完全型である場合、
- それ以外の場合、decay-copy(t.end())(C++23まで)auto(t.end())(C++23以降)、この式が有効であり、その型が std::sentinel_for<ranges::iterator_t<T>> をモデル化する場合。
- それ以外の場合、decay-copy(end(t))(C++23まで)auto(end(t))(C++23以降)、
Tがクラス型または列挙型であり、この式が有効で、その変換された型が std::sentinel_for<ranges::iterator_t<T>> をモデル化する場合。ここで、endの意味は、引数依存探索のみを実行した場合と同様に確立されます。
上記以外のすべてのケースでは、ranges::end の呼び出しは不正形式であり、テンプレートインスタンス化の直接のコンテキストで ranges::end の呼び出しが現れる場合、置換失敗につながる可能性があります。
目次 |
カスタマイゼーションポイントオブジェクト
ranges::end という名前は、カスタマイゼーションポイントオブジェクト を表します。これは、関数オブジェクトであり、リテラルな semiregular クラス型の const オブジェクトです。説明のために、その型の cv 修飾されていないバージョンは __end_fn と表記されます。
__end_fn のすべてのインスタンスは等価です。同じ引数に対して異なる __end_fn 型のインスタンスを呼び出した場合の効果は、インスタンスを表す式が左辺値か右辺値か、および const 修飾されているかどうかにかかわらず同等です(ただし、volatile 修飾されたインスタンスは呼び出し可能であることが保証されていません)。したがって、ranges::end は自由にコピーでき、そのコピーは互換性があります。
型のセット Args... が与えられた場合、std::declval<Args>()... が上記の ranges::end の引数要件を満たす場合、__end_fn は以下をモデル化します。
- std::invocable<__end_fn, Args...>,
- std::invocable<const __end_fn, Args...>,
- std::invocable<__end_fn&, Args...>、および
- std::invocable<const __end_fn&, Args...>.
それ以外の場合、__end_fn の関数呼び出し演算子のいずれもオーバーロード解決に参加しません。
[編集] 注釈
引数が右辺値(つまり T がオブジェクト型)であり、ranges::enable_borrowed_range<std::remove_cv_t<T>> が false である場合、または境界が不明な配列型である場合、ranges::end の呼び出しは不正形式であり、置換失敗にもつながります。
もし ranges::end(std::forward<T>(t)) が有効である場合、decltype(ranges::end(std::forward<T>(t))) と decltype(ranges::begin(std::forward<T>(t))) は、T が std::ranges::range をモデル化する間、すべてのケースで std::sentinel_for をモデル化します。
C++20 標準では、基になる end 関数呼び出しが prvalue を返す場合、戻り値はマテリアライズされた一時オブジェクトからムーブ構築される必要があります。すべての実装では、代わりに prvalue を直接返します。この要件は、実装に一致するように、C++20 後プロポーザル P0849R8 によって修正されています。
[編集] 例
#include <algorithm> #include <iostream> #include <ranges> #include <vector> int main() { std::vector<int> vec{3, 1, 4}; if (std::ranges::find(vec, 5) != std::ranges::end(vec)) std::cout << "found a 5 in vector vec!\n"; int arr[]{5, 10, 15}; if (std::ranges::find(arr, 5) != std::ranges::end(arr)) std::cout << "found a 5 in array arr!\n"; }
出力
found a 5 in array arr!
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| P2602R2 | C++20 | ADL によって見つけられる特定の非メンバー end を禁止する仕組みがあります。 |
その仕組みは削除されました。 |
[編集] 関連項目
| (C++20) |
読み取り専用rangeの終端を示す番兵を返す (カスタマイゼーションポイントオブジェクト) |
| (C++20) |
rangeの先頭を指すイテレータを返す (カスタマイゼーションポイントオブジェクト) |
| (C++11)(C++14) |
コンテナまたは配列の末尾を指すイテレータを返す (関数テンプレート) |