티스토리 뷰
C++에서 반복문의 대명사 for문으로 배열이나 container에 순차적으로 접근할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> // cout #include <vector> // vector #include <algorithm> // for_each using namespace std; int main() { vector<int> nums = {1, 2, 3, 4, 5}; // 1. using for loop for (int i = 0; i < 5; i++){ cout << nums[i] << ' '; // vector의 원소를 순차적으로 출력 } // 2. using ranged-based for loop for (auto &i: nums) { cout << i << ' '; // vector의 원소를 순차적으로 출력 i += 2; // 각 원소에 2를 더해줌. } } | cs |
다만, 각 원소에 대한 작업을 쉽게 해 줄 수 있는 STL 함수가 있으니, std::for_each로 한 번에 처리하여보자.
1. for_each
(※ https://www.cplusplus.com/reference/algorithm/for_each/에서 함수에 대한 정보를 확인할 수 있다.)
C++의 알고리즘 관련 헤더 <algorithm.h>에는 for_each라는 함수는 다음과 같은 구조를 가진다.
Function for_each(InputIterator first, InputIterator last, Function fn)
for_each는 3개의 인자를 받는다.
- InputIterator first: 배열이나 어떤 container 자료형의 시작부 혹은 포인터
- InputIterator last: 배열이나 어떤 container 자료형의 끝부 혹은 포인터
- Function fn: 배열이나 container의 각 원소에 수행할, 인자가 1개인 함수. 함수 객체와 함수 포인터 모두 가능하다. 이 함수의 반환값은 무시된다.
for_each 함수의 반환값은 전달된 함수 객체이므로, 보통 무시해도 된다.
구체적으로 이 함수의 역할을 말하자면, 범위 [first, last)에서 각 원소에 적용할 함수 fn을 적용한다. for_each 함수는 기존 원소를 변형하기에 기존 원소를 보존하거나 결과를 다른 곳에 보관할 경우 다른 함수를 사용해야 한다. 만약 이해가 안 된다면, 같은 역할을 하는 코드를 작성하면 다음과 같이 작성할 수 있다.
1 2 3 4 5 6 7 8 9 10 | template <class InputIterator, class Function> Function for_each(InputIterator first, InputIterator last, Function fn) { while (first!=last) { fn (*first); ++first; } return fn; // C++11 이후부터는 move(fn) } | cs |
쉽게 말해, 배열 안의 값들에 함수를 적용시켜준다고 할 수 있다.
2. 예제 코드
위의 각 배열을 for문 대신 for_each를 이용하여 출력하고, 각 원소에 2를 더한다고 하면, 다음과 같이 작성할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> // cout #include <vector> // vector #include <algorithm> // for_each using namespace std; void func(const int& x) { cout << x << ' '; } int add_2(int& x) { x += 2; return 100; // return값은 무시됨. } int main() { vector<int> nums = {1, 2, 3, 4, 5}; // for_each를 이용한 출력 for_each(nums.begin(), nums.end(), func); // 각 원소에 2를 더함 for_each(nums.begin(), nums.end(), add_2); for (const auto& x: nums) { cout << x << ' '; } // cout : 3 4 5 6 7 } | cs |
이렇게 쓰고 나면, for문과 같은 역할을 하지 않냐는 이야기를 할 수 있다.
옳은 이야기이다. for_each는 for문과 거의 동일한 역할을 하고 있다고 해도 무방하다. 적용할 함수의 인자로 레퍼런스를 사용한다면 원소 내의 값도 수정할 수 있다. C++11부터 지원되는 range-based for문이 도입됨에 따라 for_each 함수의 필요성은 거의 사라졌다.
그래도 사용하는 이유를 꼽자면, for_each를 사용하면 함수로 코드를 관리하기 때문에 코드의 가독성을 높일 수 있다.
또한, C++17부터는 STL 병렬화를 위한 Execution Policy를 직접 인자로 추가할 수 있고, 이는 for문과는 다른 양상을 띄게 된다. 이 이야기는 ExecutionPolicy에 관한 이야기를 할 때 하겠다.
도움이 되었다면 지나가는 길에 하트 하나 눌러주세요, 양질의 글을 쓰는데 하나의 동기부여가 됩니다😍
지적이나 오타 수정 댓글 환영합니다!!
'C++' 카테고리의 다른 글
[C / C++] Call by value(값에 의한 호출), Call by Reference(참조에 의한 호출), 무엇이 다르지? (0) | 2022.05.11 |
---|---|
[C / C++] return 0; 는 왜 종료의 표준이 되었나? 프로그램 종료에 대한 이해 (1) | 2022.04.25 |
[C++] 두 배열을 함수 한 방에 아주 쉽게 비교하자! equal (0) | 2022.04.17 |
[C++] 배열 안을 함수 한 번에 회전시켜보자! rotate (0) | 2022.04.17 |
[C++] 누적 합을 함수 한 방에 구하여보자! partial_sum (0) | 2022.04.14 |
- Total
- Today
- Yesterday
- 시간복잡도
- JS
- Python
- C
- C++
- 문자열
- 사칙연산
- 구현
- docker
- Proactor
- BOJ
- 프로그래밍
- equal
- 수학
- bomblab
- Network
- 백준
- 헤더
- effective async
- BRONZE
- MIN
- react
- 제어문
- GDSC
- for
- CSAPP
- 함수
- 알고리즘
- Max
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |