std::advance
From cppreference.com
| ヘッダ <iterator> で定義 |
||
template< class InputIt, class Distance > void advance( InputIt& it, Distance n ); |
(C++17まで) | |
template< class InputIt, class Distance > constexpr void advance( InputIt& it, Distance n ); |
(C++17以降) | |
与えられたイテレータ it を n 要素だけ進めます。
n が負の場合、イテレータは後退します。この場合、InputIt は LegacyBidirectionalIterator の要件を満たしている必要があります。それ以外の場合、動作は未定義です。
目次 |
[編集] パラメータ
| it | - | 進めるイテレータ |
| n | - | it を進める要素数 |
| 型要件 | ||
-InputIt は LegacyInputIterator の要件を満たす必要があります。 | ||
[編集] 返り値
(なし)
[編集] 計算量
線形。
ただし、InputIt がさらに LegacyRandomAccessIterator の要件を満たす場合、計算量は定数時間。
[編集] 注記
指定されたインクリメントまたはデクリメントのシーケンスが、インクリメント不能なイテレータ(終了後イテレータなど)のインクリメント、またはデクリメント不能なイテレータ(先頭イテレータまたは 特異な イテレータ)のデクリメントを必要とする場合、動作は未定義です。
[編集] 実装例
libstdc++ および libc++ の実装も参照してください。
| 非constexpr版 |
|---|
namespace detail { template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::input_iterator_tag) { while (n > 0) { --n; ++it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::bidirectional_iterator_tag) { while (n > 0) { --n; ++it; } while (n < 0) { ++n; --it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::random_access_iterator_tag) { it += n; } } // namespace detail template<class It, class Distance> void advance(It& it, Distance n) { detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n), typename std::iterator_traits<It>::iterator_category()); } |
| constexpr版 |
template<class It, class Distance> constexpr void advance(It& it, Distance n) { using category = typename std::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); auto dist = typename std::iterator_traits<It>::difference_type(n); if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) it += dist; else { while (dist > 0) { --dist; ++it; } if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>) while (dist < 0) { ++dist; --it; } } } |
[編集] 例
このコードを実行
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; auto vi = v.begin(); std::advance(vi, 2); std::cout << *vi << ' '; vi = v.end(); std::advance(vi, -2); std::cout << *vi << '\n'; }
出力
4 1
[編集] 関連項目
| (C++11) |
イテレータをインクリメントする (関数テンプレート) |
| (C++11) |
イテレータをデクリメントする (関数テンプレート) |
| 2つのイテレータ間の距離を返す (関数テンプレート) | |
| (C++20) |
イテレータを指定された距離または指定された境界まで進める (アルゴリズム関数オブジェクト) |