제가 이 게시판에 STL 관련팁을 올린 것도 벌써 40개가 훨씬 넘었네요.
지금까지 웬만큼 중요한 STL 알고리듬을 대부분 소개했지만,
가장 중요한 알고리듬을 설명 안했군요.
바로 for_each 알고리듬 입니다.
"주어진 범위의 각각의 원소에 대해서 특정 동작을 호출한다"라고 정의 되어 있는데요,
이것은 사실 모든 STL 알고리듬이 동작하는 원리입니다.
즉, 다른 모든 STL 알고리듬은 for_each 알고리듬의 특화된 버전이라고 보시면 됩니다.
반대로 말하면 for_each가 STL 알고리듬 중 가장 범용적인 알고리듬입니다.
즉, 하고자 하는 작업이 다른 알고리듬으로 해결할 수 있을 때는 for_each() 알고리듬을 사용하지 않는 것이 좋습니다.
다른 알고리듬이 없을 때 최후의 수단으로 사용해야겠죠.
하여튼 for나 while 등의 루프를 사용하는 코드는 대부분 for_each를 비롯한 STL 알고리듬을 사용한 코드로 바꾸어서 가독성을 향상시킬 수 있습니다. 물론 이렇게 했을 때 오히려 구현이 너무 까다로워지는 경우도 있을 수 있습니다. 이럴때는 그냥 루프를 쓰세요.
그리고, 다른 알고리듬에는 없는 for_each의 강력한 기능은
적용한 함수 객체의 마지막 상태를 반환한다는 점입니다.
물론 다른 알고리듬도 함수 객체를 값으로 전달하지 않고, 참조로 전달하는 방식으로
함수 객체의 마지막 상태를 알 수 있지만, 디폴트가 아니므로 호출 방식이 꽤 복잡할 뿐만 아니라,
일반적으로 추천하는 방식이 아닙니다. 컴파일러에 따라서는 아예 컴파일이 되지 않을 수도 있습니다. (자세한 내용은 'The C++ Standard Library: A Tutorial and Reference'의 Ch.8.1.2와
'Effective STL'의 Item 38을 참고하세요.)
다음은 이러한 기능을 쓴 예제로,
임의의 정수 n을 입력받아 n까지의 홀수와 짝수의 합을 계산하는 프로그램입니다.
일반적인 합이라면 accumulate 알고리듬을 쓰면 간단하지만, 이 경우에는 accumulate로는 불가능합니다.
///---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop
#include <vector>
#include <iterator>
#include <algorithm>
//---------------------------------------------------------------------------
using namespace std;
class IntSeq
{
public:
IntSeq(int init): n(init) {}
int operator()() { return n++; }
private:
int n;
};
class OddAndEvenSum: public unary_function<int, void>
{
public:
OddAndEvenSum(): odds(0), evens(0) {}
void operator()(int n)
{
if (n % 2 == 0)
evens += n;
else
odds += n;
}
// 결과를 얻기위한 멤버함수들
int OddSum() const { return odds; }
int EvenSum() const { return evens; }
private:
int odds, evens;
};
int main()
{
int n;
cout << "n = "; cin >> n;
vector<int> series(n);
generate(series.begin(), series.end(), IntSeq(1));
OddAndEvenSum sums = for_each(series.begin(), series.end(), OddAndEvenSum());
cout << "The sum of odd numbers = " << sums.OddSum();
cout << "\nThe sum of even numbers = " << sums.EvenSum() << endl;
return 0;
}
//---------------------------------------------------------------------------
|