名前空間
変種
操作

std::distance

From cppreference.com
 
 
イテレータライブラリ
イテレータのコンセプト
イテレータのプリミティブ
アルゴリズムのコンセプトとユーティリティ
間接呼び出し可能コンセプト
共通アルゴリズム要件
(C++20)
(C++20)
(C++20)
ユーティリティ
(C++20)
イテレータアダプタ
イテレータ操作
distance
(C++11)  
(C++11)
Rangeアクセス
(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< class InputIt >

typename std::iterator_traits<InputIt>::difference_type

    distance( InputIt first, InputIt last );
(C++17 以降 constexpr)

firstからlastまでのホップ数を返します。

InputItLegacyRandomAccessIteratorでない場合、lastfirstから到達可能でない場合、動作は未定義です。

InputItLegacyRandomAccessIteratorである場合、firstlastがお互いに到達可能でない場合、動作は未定義です。

目次

[編集] パラメータ

first - 最初の要素を指すイテレータ
最後 - 範囲の末尾を指すイテレータ
型要件
-
InputItLegacyInputIteratorの要件を満たす必要があります。InputItがさらにLegacyRandomAccessIteratorの要件を満たす場合、操作はより効率的になります。

[編集] 戻り値

firstからlastへ移動するために必要なインクリメント数。

ランダムアクセス dinyatakan が使用され、firstlast から到達可能な場合、値は負になることがあります。

(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());
}
if constexprによるC++17実装
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';
              // the behavior is undefined (until LWG940)
 
    static constexpr auto il = {3, 1, 4};
    // Since C++17 `distance` can be used in constexpr context.
    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 firstlastから到達可能な場合の記述が不明確でした 明確化された

[編集] 関連項目

イテレータを指定された距離だけ進める
(関数テンプレート) [編集]
特定の基準を満たす要素の数を返す
(関数テンプレート) [編集]
イテレータと番兵 (sentinel) の間の距離、またはRangeの始点と終点の間の距離を返す
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)