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

履歴 編集

function template
<algorithm>

std::ranges::for_each_n(C++20)

namespace std::ranges {
  template <input_iterator I,
            class Proj = identity,
            indirectly_unary_invocable<projected<I, Proj>> Fun>
  constexpr for_each_n_result<I, Fun>
    for_each_n(I first,
               iter_difference_t<I> n,
               Fun f,
               Proj proj = {}); // (1) C++20
}

概要

範囲の先頭N個の要素に、指定された関数を適用する。

テンプレートパラメータ制約

この他にFunはcopy_constructibleのモデルであることが要求される。

事前条件

n >= 0

効果

イテレータ範囲[first, first + n) 内の全てのイテレータ iinvoke(f,invoke(proj, *i)) という操作を行う。

このアルゴリズムはその他のアルゴリズムと違い、invoke(proj, *i) が書き換え可能な参照であれば、関数 f の内部でその値を書き換えても構わない。

戻り値

for_each_n_result {
  .in = first + n,
  .fun = std::move(f)
}

備考

  • 関数 f に戻り値がある場合、それは単に無視される

#include <iostream>
#include <algorithm>
#include <array>

void f(int& x)
{
  x *= 2;
}

int main()
{
  constexpr std::array<int> v = {3, 1, 4, 5, 2};

  // コンテナvの先頭3要素に、関数f()を適用する。
  // 関数f()は要素の変更を行う
  std::ranges::for_each_n(v.begin(), 3, f);

  // コンテナvの先頭3要素に、ラムダ式で記述した関数オブジェクトを適用する
  std::ranges::for_each_n(v.begin(), 3, [](int x) {
    std::cout << x << std::endl;
  });
}

出力

6
2
8

処理系

実装例

struct for_each_n_impl {
  template<input_iterator I, class Proj = identity, indirectly_unary_invocable<projected<I, Proj>> Fun>
    requires copy_constructible<Fun>
  constexpr for_each_n_result<I, Fun> operator()(I first, iter_difference_t<I> n, Fun f, Proj proj = {}) const {
    for (iter_difference_t<I> i = 0; i < n; ++i) {
      invoke(f, invoke(proj, *first));
      ++first;
    }
    return {move(first), move(f)};
  }
};

inline constexpr for_each_n_impl for_each_n;

参照