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

履歴 編集

concept
<iterator>

std::weakly_incrementable(C++20)

namespace std {
  template<class I>
  concept weakly_incrementable =
    default_initializable<I> && movable<I> &&
    requires(I i) {
      typename iter_difference_t<I>;
      requires is-signed-integer-like<iter_difference_t<I>>;
      { ++i } -> same_as<I&>;   // 等しさを保持することを要求しない
      i++;                      // 等しさを保持することを要求しない
    };
}

概要

weakly_incrementableは、イテレータ型Iが前置/後置インクリメント演算子(operator++)によってインクリメント可能であることを表すコンセプトである。

そのようなインクリメント操作には等しさを保持することは要求されず、型Iは等値比較可能(equality_comparable)である必要もない。

モデル

Iのオブジェクトiについて次の条件を満たす場合に限って、型Iweakly_incrementableのモデルである。

  • ++ii++は同じ定義域を持つ
  • iがインクリメント可能ならば、++ii++iを次の要素へ進める
  • iがインクリメント可能ならば、addressof(++i)addressof(i)は等値となる

iがインクリメント可能」というのは、iが前置/後置両方のインクリメント式(++)の定義域にある場合を言う。すなわち、一般的なイテレータ範囲のendなどインクリメントが出来ない、あるいは未定義動作となるような状態にiが無い場合を指定している。

備考

このコンセプトはイテレータにマルチパス保証を要求しない。例えばイテレータa, bがある時、a == bであっても++a == ++bとなるとは限らない。すなわち、weakly_incrementableなイテレータはその操作によってイテレータが参照しているシーケンスの状態が変更されることを許可する。そのようなイテレータには例えばistream_iteratorがある。

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

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

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


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

  // これも必要
  using difference_type = int;
};

struct sample_not_weak_incrementable {
  // 前置++しか用意しない
  friend auto operator++(sample_weak_incrementable&) -> sample_weak_incrementable&;

  using difference_type = int;
};


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

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

出力

int* is weakly incrementable
const int* is weakly incrementable
std::vector<int>::iterator is weakly incrementable
std::ostream_iterator<double> is weakly incrementable
sample_incrementable is weakly incrementable

int* const is not weakly incrementable
std::unique_ptr<int> is not weakly incrementable
sample_not_incrementable is not weakly incrementable

バージョン

言語

  • C++20

処理系

関連項目

参照