모두의 코드
C++ 레퍼런스 - for_each 함수

작성일 : 2019-01-19 이 글은 3756 번 읽혔습니다.

아직 C++ 에 친숙하지 않다면 씹어먹는 C++ 은 어때요?

for_each

<algorithm> 에 정의됨

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 은 아래와 같이 정의될 수 있습니다.

void fun(const Type &a);

이 때, 인자의 경우 꼭 const& 일 필요는 없습니다. 또한, 반복자를 역참조한 타입이 Type 과 일치(혹은 Type 으로 변환 될 수 있어야 함) 해야 합니다.

리턴값

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

std::transform 과의 관계

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

  • for_each 의 경우 원소를 수정하지 않습니다. 물론 전달한 함수가 레퍼런스를 받는다면 수정할 수 있겟지만, 바람직한 사용 방식은 아닙니다. 또한 함수의 리턴값 역시 무시됩니다. 참고로 for_each 는 표준에 의해 원소들을 순차적으로 접근함이 보장됩니다.

  • transform 의 경우 원소를 수정하게 됩니다. 함수의 리턴값으로 해당 원소가 바뀝니다. 또한 for_each 와는 다르게, 순차적으로 원소를 접근함이 보장되지 않습니다 (물론 범위 내에 원소를 모두 접근하기는 하지만, 꼭 처음부터 끝까지 순서대로 하는 것은 아닙니다).

구현 예시

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

참고 자료

  • transform : 특정 범위의 원소들을 변환한다.

  • find : 범위 안에 원소들 중 값이 일치하는 원소를 찾는다.

  • search : 어떤 원소들의 나열을 검색한다.

댓글이 2 개 있습니다!
프로필 사진 없음
강좌에 관련 없이 궁금한 내용은 여기를 사용해주세요