std:: distance
|
ヘッダー
<iterator>
で定義
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
difference_type
|
(constexpr C++17以降) | |
first から last までのホップ数を返します。
InputIt
が
LegacyRandomAccessIterator
でない場合、
last
が
first
から
到達可能
でないとき、動作は未定義です。
InputIt
が
LegacyRandomAccessIterator
である場合、
first
と
last
が互いに到達可能でない場合、動作は未定義です。
目次 |
パラメータ
| first | - | 最初の要素を指すイテレータ |
| last | - | 範囲の終端を指すイテレータ |
| 型要件 | ||
-
InputIt
は
LegacyInputIterator
の要件を満たさなければならない。
InputIt
が追加で
LegacyRandomAccessIterator
の要件も満たす場合、操作はより効率的になる。
|
||
戻り値
first から last まで移動するために必要なインクリメント回数。
|
ランダムアクセスイテレータが使用され、かつ first が last から到達可能である場合、値は負になる可能性があります。 |
(C++11以降) |
計算量
線形。
ただし、
InputIt
がさらに
LegacyRandomAccessIterator
の要件を満たす場合、計算量は定数時間となります。
実装例
実装については libstdc++ および libc++ も参照してください。
| C++98 タグディスパッチによる実装、 constexpr を除去 |
|---|
namespace detail { template<class It> constexpr // required since C++17 typename std::iterator_traits<It>::difference_type do_distance(It first, It last, std::input_iterator_tag) { typename std::iterator_traits<It>::difference_type result = 0; while (first != last) { ++first; ++result; } return result; } template<class It> constexpr // required since C++17 typename std::iterator_traits<It>::difference_type do_distance(It first, It last, std::random_access_iterator_tag) { return last - first; } } // namespace detail template<class It> constexpr // since C++17 typename std::iterator_traits<It>::difference_type distance(It first, It last) { return detail::do_distance(first, last, typename std::iterator_traits<It>::iterator_category()); } |
| C++17 if constexpr による実装 |
template<class It> constexpr typename std::iterator_traits<It>::difference_type distance(It first, It last) { using category = typename std::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) return last - first; else { typename std::iterator_traits<It>::difference_type result = 0; while (first != last) { ++first; ++result; } return result; } } |
例
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; std::cout << "distance(first, last) = " << std::distance(v.begin(), v.end()) << '\n' << "distance(last, first) = " << std::distance(v.end(), v.begin()) << '\n'; // 動作は未定義(LWG940まで) static constexpr auto il = {3, 1, 4}; // C++17以降、`distance`はconstexprコンテキストで使用可能 static_assert(std::distance(il.begin(), il.end()) == 3); static_assert(std::distance(il.end(), il.begin()) == -3); }
出力:
distance(first, last) = 3 distance(last, first) = -3
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 940 | C++98 | first が last から到達可能な場合の記述が不明確であった | 明確化された |
関連項目
|
イテレータを指定された距離だけ進める
(関数テンプレート) |
|
|
特定の条件を満たす要素の数を返す
(関数テンプレート) |
|
|
(C++20)
|
イテレータとセンチネル間、または範囲の先頭と終端間の距離を返す
(アルゴリズム関数オブジェクト) |