Namespaces
Variants

std:: input_iterator_tag, std:: output_iterator_tag, std:: forward_iterator_tag, std:: bidirectional_iterator_tag, std:: random_access_iterator_tag, std:: contiguous_iterator_tag

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
input_iterator_tag output_iterator_tag forward_iterator_tag bidirectional_iterator_tag random_access_iterator_tag contiguous_iterator_tag
(C++20)
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>
struct input_iterator_tag { } ;
(1)
struct output_iterator_tag { } ;
(2)
struct forward_iterator_tag : public input_iterator_tag { } ;
(3)
struct bidirectional_iterator_tag : public forward_iterator_tag { } ;
(4)
struct random_access_iterator_tag : public bidirectional_iterator_tag { } ;
(5)
struct contiguous_iterator_tag : public random_access_iterator_tag { } ;
(6) (C++20以降)

イテレータのカテゴリを定義します。各タグは空の型です。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Iterator category、Iterator concept、Example、See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、IDは一切変更していません - 番号付けや構造は完全に保持されています - 技術文書としての正確性と専門性を維持しています

イテレータカテゴリ

すべての LegacyIterator It について、 typedef std:: iterator_traits < It > :: iterator_category は、これらのタグ型のいずれかのエイリアスとして定義されなければならず、 It が属する最も具体的なカテゴリを示す必要があります。

  1. input_iterator_tag LegacyInputIterator に対応します。
  2. output_iterator_tag LegacyOutputIterator に対応します。
  3. forward_iterator_tag LegacyForwardIterator に対応します。
  4. bidirectional_iterator_tag LegacyBidirectionalIterator に対応します。
  5. random_access_iterator_tag LegacyRandomAccessIterator に対応します。

イテレータカテゴリタグは、カテゴリによって示される特定の要件セットに対して最も効率的なアルゴリズムを選択するために使用できる情報を保持します。

Iterator concept

すべての input_iterator It について、 It :: iterator_concept std:: iterator_traits < It > がプライマリテンプレートから生成される場合)または std:: iterator_traits < It > :: iterator_concept std:: iterator_traits < It > が特殊化されている場合)は、これらのタグのいずれかのエイリアスとして宣言され、 It がモデル化する最も強いイテレータコンセプトを示す。

  1. input_iterator_tag input_iterator に対応する。
  2. forward_iterator_tag forward_iterator に対応する。
  3. bidirectional_iterator_tag bidirectional_iterator に対応する。
  4. random_access_iterator_tag random_access_iterator に対応する。
  5. contiguous_iterator_tag contiguous_iterator に対応する。

iterator_concept が提供されない場合、 iterator_category がフォールバックとして使用される。 iterator_category も提供されない場合(すなわち It LegacyIterator ではない場合)、かつ std:: iterator_traits < It > が特殊化されていない場合、 random_access_iterator_tag が仮定される。

いずれの場合も、必要な操作がサポートされていない場合、タグに関係なく各コンセプトは満たされない。

(C++20以降)

注記

LegacyContiguousIterator 専用のタグは存在しません。つまり、 iterator_category に基づいて LegacyContiguousIterator を判別することはできません。 連続イテレータ向けの特殊化されたアルゴリズムを定義するには、 contiguous_iterator コンセプトを使用してください。 (C++20以降)

output_iterator_tag output_iterator コンセプトの間には対応関係はありません。 iterator_concept output_iterator_tag に設定することは、 その型が input_iterator をモデル化していないことのみを示します。

イテレータカテゴリタグに基づくアルゴリズム選択の一般的な手法は、ディスパッチャ関数を使用することです(代替手段は std::enable_if です)。 イテレータタグクラスは、対応するコンセプト定義でも使用され、使用パターンだけでは表現できない要件を示すために用いられます。 (C++20以降)

#include <iostream>
#include <iterator>
#include <list>
#include <vector>
// Using concepts (tag checking is part of the concepts themselves)
template<std::bidirectional_iterator BDIter>
void alg(BDIter, BDIter)
{
    std::cout << "1. alg() \t called for bidirectional iterator\n";
}
template<std::random_access_iterator RAIter>
void alg(RAIter, RAIter)
{
    std::cout << "2. alg() \t called for random-access iterator\n";
}
// Legacy, using tag dispatch
namespace legacy
{
    // Quite often implementation details are hidden in a dedicated namespace
    namespace implementation_details
    {
        template<class BDIter>
        void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
        {
            std::cout << "3. legacy::alg() called for bidirectional iterator\n";
        }
        template<class RAIter>
        void alg(RAIter, RAIter, std::random_access_iterator_tag)
        {
            std::cout << "4. legacy::alg() called for random-access iterator\n";
        }
    } // namespace implementation_details
    template<class Iter>
    void alg(Iter first, Iter last)
    {
        implementation_details::alg(first, last,
            typename std::iterator_traits<Iter>::iterator_category());
    }
} // namespace legacy
int main()
{
    std::list<int> l;
    alg(l.begin(), l.end()); // 1.
    legacy::alg(l.begin(), l.end()); // 3.
    std::vector<int> v;
    alg(v.begin(), v.end()); // 2.
    legacy::alg(v.begin(), v.end()); // 4.
//  std::istreambuf_iterator<char> i1(std::cin), i2;
//  alg(i1, i2);         // compile error: no matching function for call
//  legacy::alg(i1, i2); // compile error: no matching function for call
}

出力:

1. alg() 	 called for bidirectional iterator
3. legacy::alg() called for bidirectional iterator
2. alg() 	 called for random-access iterator
4. legacy::alg() called for random-access iterator

関連項目

(C++17で非推奨)
シンプルなイテレータのための必須型定義を容易にする基底クラス
(クラステンプレート)
イテレータのプロパティに対する統一インターフェースを提供する
(クラステンプレート)