for_each

에 정의됨

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);

범위 내에 원소들에 대해 함수를 실행시킵니다.

범위 내 (first 부터 last 전 까지) 원소들 각각에 대해 함수 fn 을 실행한다. 참고로 함수의 리턴값은 무시됩니다.

인자

  • first, last : 원소들의 시작과 끝을 가리키는 반복자들. 이 때 확인하는 범위는 [first, last) 로 정의됩니다. first 가 가리키는 원소는 포함되지만 last 가 가리키는 원소는 포함되지 않습니다.
  • fn : 인자를 하나만 받는 함수 객체. 범위 내에 원소들 각각에 대해 함수 fn 을 호출하게 됩니다.

참고로 fn 은 아래와 같이 정의될 수 있습니다.

리턴값

전달된 함수 객체(fn)를 리턴합니다.

std::transform 과의 관계

transform 함수, for_each 함수와 하는 일은 거의 동일합니다. transform 함수 역시, 범위 내에 원소들에 대해 전달된 함수를 호출하게 됩니다. 다만, 두 함수가 하는 역할은 조금 다른데

  • for_each의 경우 원소를 수정하지 않습니다. 물론 전달한 함수가 레퍼런스를 받는다면 수정할 수 있겟지만, 바람직한 사용 방식은 아닙니다. 또한 함수의 리턴값 역시 무시됩니다. for_each는 표준에 의해 원소들을 순차적으로 접근함이 보장됩니다.
  • transform 의 경우 원소를 수정하게 됩니다. 함수의 리턴값으로 해당 원소가 바뀝니다. 또한 for_each 와는 다르게, 순차적으로 원소를 접근함이 보장되지 않습니다 (물론 범위 내에 원소를 모두 접근하기는 하지만, 꼭 처음부터 끝까지 순서대로 하는 것은 아닙니다).

구현 예시

C/C++ 확대 축소

template <class InputIt, class UnaryFunction>
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f) {
  for (; first != last; ++first) {
    f(*first);
  }
  return f;
}

실행 예제

#include <algorithm>  // std::for_each
#include <iostream>   // std::cout
#include <vector>     // std::vector

void myfunction(int i) {  // function:
  std::cout << ' ' << i;
}

struct myclass {  // function object type:
  void operator()(int i) { std::cout << ' ' << i; }
} myobject;

int main() {
  std::vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  // 일반적인 함수 포인터 전달
  std::cout << "myvector contains:";
  for_each(myvector.begin(), myvector.end(), myfunction);
  std::cout << '\n';

  // Functor 를 전달
  std::cout << "myvector contains:";
  for_each(myvector.begin(), myvector.end(), myobject);
  std::cout << '\n';

  // 람다 함수를 전달
  std::cout << "myvector contains:";
  for_each(myvector.begin(), myvector.end(),
           [](const int& n) { std::cout << ' ' << n; });
  std::cout << '\n';

  return 0;
}

실행 결과

myvector contains: 10 20 30
myvector contains: 10 20 30
myvector contains: 10 20 30