Namespaces
Variants

std::ranges:: prev

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
ヘッダーで定義 <iterator>
呼び出しシグネチャ
template < std:: bidirectional_iterator I >
constexpr I prev ( I i ) ;
(1) (C++20以降)
template < std:: bidirectional_iterator I >
constexpr I prev ( I i, std:: iter_difference_t < I > n ) ;
(2) (C++20以降)
template < std:: bidirectional_iterator I >
constexpr I prev ( I i, std:: iter_difference_t < I > n, I bound ) ;
(3) (C++20以降)

n th 番目の前駆イテレータを返す i

このページで説明されている関数ライクな実体は、 アルゴリズム関数オブジェクト (非公式には niebloids として知られる) です。つまり:

目次

パラメータ

i - イテレータ
n - 要素数 i が降下すべき回数
bound - i が指す範囲の先頭を示すイテレータ

戻り値

1) i の前身。
2) イテレータ i n th 番目の前駆体。
3) イテレータ i n 番目の前駆体、または bound と等しく比較される最初のイテレータのうち、どちらか先に来る方。

計算量

1) 定数。
2,3) I std:: random_access_iterator < I > をモデル化する場合は定数時間、それ以外の場合は線形時間。

実装例

struct prev_fn
{
    template<std::bidirectional_iterator I>
    constexpr I operator()(I i) const
    {
        --i;
        return i;
    }
    template<std::bidirectional_iterator I>
    constexpr I operator()(I i, std::iter_difference_t<I> n) const
    {
        ranges::advance(i, -n);
        return i;
    }
    template<std::bidirectional_iterator I>
    constexpr I operator()(I i, std::iter_difference_t<I> n, I bound) const
    {
        ranges::advance(i, -n, bound);
        return i;
    }
};
inline constexpr auto prev = prev_fn();

注記

-- r. end ( ) はコンテナに対してコンパイルが通ることが多いものの、保証されているわけではありません: r. end ( ) は右辺値式であり、右辺値のデクリメントが動作することが保証されていることを規定するイテレータ要件は存在しません。特に、イテレータがポインタとして実装されている場合や、 operator-- が左辺値参照修飾されている場合、 -- r. end ( ) はコンパイルできませんが、 ranges :: prev ( r. end ( ) ) はコンパイルできます。

これはさらに、 ranges:: common_range をモデル化しない範囲によって悪化します。例えば、一部の基盤となる範囲では、 ranges :: transform_view :: end の戻り値型が ranges :: transform_view :: begin と同じではないため、 -- r. end ( ) はコンパイルされません。これは ranges::prev が支援できるものではありませんが、回避策は存在します。

#include <iostream>
#include <iterator>
#include <vector>
int main() 
{
    std::vector<int> v{3, 1, 4};
    auto pv = std::ranges::prev(v.end(), 2);
    std::cout << *pv << '\n';
    pv = std::ranges::prev(pv, 42, v.begin());
    std::cout << *pv << '\n';
}

出力:

1
3

関連項目

指定された距離または境界までイテレータをインクリメントする
(アルゴリズム関数オブジェクト)
指定された距離または指定された境界までイテレータを進める
(アルゴリズム関数オブジェクト)
(C++11)
イテレータをデクリメントする
(関数テンプレート)