1 minute read

for_each 알고리즘으로 대체 구현이 가능한 거라 한 번도 사용해보지 않은 알고리즘이다. Effective STL 37번 항목에서 accumulate알고리즘에 대한 언급이 나오는데, 으.. 읽고 보니 좋은 걸 안 쓰고 있었구나.

시작과 끝점을 주고는 그 범위를 요약(summarize)하는데 사용하는 알고리즘이라는 걸 온몸으로 말하고 있다. for_each 라는 친근한 알고리즘으로 대체 구현이 가능하지만, for_each 는 컨테이너의 원소에 대해 하나하나 연산을 하는 의미로 다가오는 반면 accumulate 원소들을 연산해서 하나의 값으로 만드는 의미로 다가온다.

accumulate 관련된 글을 읽으니 예전에 짠 코드가 떠올랐다.

class MeanValue
{
public:
    MeanValue() : m_sum(0.0f), m_count(0)   {}

    void operator() (double elem)
    {
        m_sum += elem;
        ++m_count;
    }

    operator double() { return m_sum / m_count; }

private:
    double  m_sum;
    int     m_count;
};

double meanValue = for_each(
    m_expenseList.begin(), m_expenseList.end(), MeanValue());

평균값이 필요해서 평균값 계산을 위한 functor를 만들고 for_each 로 구했는데, 재활용할 수 있으면 짜겠지만 한 번 쓰려고 저렇게 하기는 부담스럽다. 반복자 대신에 알고리즘을 쓰려고 하다가 빠진 함정 같기도 하고.

assert(!m_expenseList.empty());
if (!m_expenseList.empty())
{
    double meanValue =
        accumulate(m_expenseList.begin(), m_expenseList.end(), 0.0) /
        m_expenseList.size();
}

위 같은 경우는 accumulate 를 사용하면 가독성도 좋을뿐더러 간단하게 구현할 수 있다.

알고리즘으로 대체 가능하면 반복자(iterator)로 컨테이너를 순회하면서 연산하지 말라고 Effective STL에서 강조하면서 알고리즘을 사용해서 얻을 수 있는 이점을 설명한다. 그 중 가독성이 알고리즘이 훨씬 좋다고 하는데, 이 부분은 동감. 반복자로 순회하는 경우는 파고들어가서 핵심 연산을 하는 부분을 봐야지 알지만, 알고리즘으로 대체한 경우는 핵심 연산이 어느 부분인지 한 번에 눈에 들어온다.

STL은 아직도 모르는 게 너무 많은 거 같다.