----------------
title : C++ 레퍼런스 - for_each 함수
cat_title : for_each
ref_title : for_each, std::for_each
path : /C++ Reference/algorithm
publish_date : 2019-01-19
----------------

##@ cpp-ref-start

#@ for_each

`<algorithm>` 에 정의됨

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

```cpp-formatted
void fun(const Type &a);
```

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


### 리턴값

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

### std::transform 과의 관계

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

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

### 구현 예시

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

### 실행 예제

```cpp-formatted
#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;
}
```

실행 결과

```exec
myvector contains: 10 20 30
myvector contains: 10 20 30
myvector contains: 10 20 30
```

### 참고 자료

* `transform` : 특정 범위의 원소들을 변환한다.
* `find$algorithm` : 범위 안에 원소들 중 값이 일치하는 원소를 찾는다.
* `search` : 어떤 원소들의 나열을 검색한다.