名前空間
変種
操作

std::ranges::rend

From cppreference.com
< cpp‎ | ranges
 
 
Rangesライブラリ
Rangeアダプタ
 
ヘッダ <ranges> で定義
ヘッダ <iterator> で定義
inline namespace /* 未指定 */ {

    inline constexpr /* unspecified */ rend = /* unspecified */;

}
(C++20以降)
(カスタマイズポイントオブジェクト)
呼び出しシグネチャ
template< class T >

    requires /* 以下を参照 */
constexpr std::sentinel_for<

    decltype(ranges::rbegin(std::declval<T>()))> auto rend( T&& t );
(C++20以降)

逆順範囲の終端を示すセンチネルを返します。

range-rbegin-rend.svg

T が配列型であり、std::remove_all_extents_t<std::remove_reference_t<T>> が不完全型の場合、ranges::rend の呼び出しは不正形式となり、診断は要求されません。

引数が左辺値であるか、または ranges::enable_borrowed_range<std::remove_cv_t<T>>true の場合、ranges::rend の呼び出しは、

  1. decay-copy(t.rend())(until C++23)auto(t.rend())(since C++23) と式等価です。
  2. それ以外の場合、decay-copy(rend(t))(until C++23)auto(rend(t))(since C++23) は、T がクラス型または列挙型であり、その式が有効で、その型が std::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))> をモデルとする場合に有効であり、この場合の `rend` の意味は、引数依存探索のみを実行した場合のそれと同様に確立されます。
  3. それ以外の場合、std::make_reverse_iterator(ranges::begin(t)) は、ranges::begin(t)ranges::end(t) の両方が有効な式であり、同じ型を持ち、その型が std::bidirectional_iterator をモデルとする場合に有効です。

それ以外の場合、ranges::rend の呼び出しは不正形式となり、テンプレートインスタンス化の直接のコンテキストに ranges::rend(t) が現れると SFINAE の原因となることがあります。

目次

カスタマイゼーションポイントオブジェクト

ranges::rend という名前は、関数オブジェクトであり、リテラルsemiregular クラス型の定数である *customization point object* を示します。説明のために、その型の cv-unqualified バージョンは __rend_fn と表記されます。

__rend_fn のすべてのインスタンスは等価です。同じ引数に対して異なる __rend_fn 型のインスタンスを呼び出す効果は、インスタンスを示す式が左辺値か右辺値か、または const 修飾されているかどうかにかかわらず同等です(ただし、volatile 修飾されたインスタンスは呼び出し可能である必要はありません)。したがって、ranges::rend は自由にコピーでき、そのコピーは相互に交換可能に使用できます。

型のセット Args... が与えられた場合、std::declval<Args>()... が上記の ranges::rend の引数要件を満たす場合、__rend_fn は以下をモデルとします。

それ以外の場合、__rend_fn の関数呼び出し演算子のいずれもオーバーロード解決に参加しません。

[編集] 注記

引数が右辺値(つまり T がオブジェクト型)であり、ranges::enable_borrowed_range<std::remove_cv_t<T>>false であるか、または未知の境界を持つ配列型である場合、ranges::rend の呼び出しは不正形式となり、これも SFINAE の原因となります。

もし ranges::rend(std::forward<T>(t)) が有効であるなら、decltype(ranges::rend(std::forward<T>(t)))decltype(ranges::begin(std::forward<T>(t))) はすべてのケースで std::sentinel_for をモデルとし、一方 Tstd::ranges::range をモデルとします。

C++20 標準は、基となる rend 関数呼び出しが prvalue を返す場合、その戻り値はマテリアライズされた一時オブジェクトからムーブ構築されることを要求しています。すべての実装は代わりに prvalue を直接返します。この要件は、実装に合わせるために C++20 以降の提案 P0849R8 によって修正されています。

[編集]

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
 
int main()
{
    std::vector<int> v = {3, 1, 4};
    namespace ranges = std::ranges;
    if (ranges::find(ranges::rbegin(v), ranges::rend(v), 5) != ranges::rend(v))
        std::cout << "found a 5 in vector v!\n";
 
    int a[] = {5, 10, 15};
    if (ranges::find(ranges::rbegin(a), ranges::rend(a), 5) != ranges::rend(a))
        std::cout << "found a 5 in array a!\n";
}

出力

found a 5 in array a!

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
P2602R2 C++20 ADL によって見つかる特定の非メンバ rend を禁止する仕組みがあります。 その仕組みは削除されました。

[編集] 関連項目

読み取り専用rangeへの逆終端イテレータを返す
(カスタマイゼーションポイントオブジェクト)[編集]
rangeへの逆イテレータを返す
(カスタマイゼーションポイントオブジェクト)[編集]
(C++14)
コンテナまたは配列の逆順の終端イテレータを返す
(function template) [編集]
English 日本語 中文(简体) 中文(繁體)