最終更新日時(UTC):
が更新

履歴 編集

concept
<iterator>

std::output_iterator(C++20)

namespace std {
  template<class I, class T>
  concept output_iterator =
    input_or_output_iterator<I> &&
    indirectly_writable<I, T> &&
    requires(I i, T&& t) {
      *i++ = std::forward<T>(t);  // 等しさを保持することを要求しない
    };
}

概要

output_iteratorは、イテレータ型Iが出力イテレータであることを表すコンセプトである。

output_iteratorとなるイテレータは、operator*による書き込みと前置/後置インクリメントによる進行が可能であるが、等値比較は必ずしも可能ではない。

モデル

decltype((E))が型Tを示す式E、間接参照可能な型Iのオブジェクトiについて次の条件を満たす場合に限って、型I, Toutput_iteratorのモデルである。

  • *i++ = E;は次の式と等価となる
    *i = E;
    ++i;
    

出力イテレータを用いるアルゴリズムは、同じイテレータ範囲を2回以上イテレートしてはならない。そのようなアルゴリズムはシングルパス(一回だけ走査する)でなければならない。

#include <iostream>
#include <concepts>
#include <iterator>
#include <memory>
#include <vector>

template<std::output_iterator<int> I>
void f(const char* name) {
  std::cout << name << " is output_iterator<int>" << std::endl;
}

template<typename I>
void f(const char* name) {
  std::cout << name << " is not output_iterator<int>" << std::endl;
}


struct sample_output_iterator {
  friend auto operator++(sample_output_iterator&) -> sample_output_iterator&;
  friend auto operator++(sample_output_iterator&, int) -> sample_output_iterator;

  friend auto operator*(const sample_output_iterator&) -> int&;

  using difference_type = int;
};


int main() {
  f<int*>("int*");
  f<std::vector<int>::iterator>("std::vector<int>::iterator");
  f<std::ostream_iterator<int>>("std::ostream_iterator<int>");
  f<sample_output_iterator>("sample_output_iterator");

  std::cout << "\n";
  f<const int*>("const int*");
  f<std::istream_iterator<int>>("std::istream_iterator<int>");
  f<int* const>("int* const");
}

出力

int* is output_iterator<int>
std::vector<int>::iterator is output_iterator<int>
std::ostream_iterator<int> is output_iterator<int>
sample_output_iterator is output_iterator<int>

const int* is not output_iterator<int>
std::istream_iterator<int> is not output_iterator<int>
int* const is not output_iterator<int>

バージョン

言語

  • C++20

処理系

関連項目

参照