IMCAT.DEV
로그인 가입
C++ 중급 함수형

C++ 함수형 프로그래밍 패턴

C++ 함수형 프로그래밍 패턴 — 중급

함수형 프로그래밍 패턴

1. 도입 (왜 배워야 하는가)

C++는 객체지향 프로그래밍(OOP)으로 잘 알려져 있지만, 함수형 프로그래밍 패턴도 매우 중요합니다. 함수형 프로그래밍은 코드의 재사용성과 가독성을 높여주며, 특히 복잡한 문제를 해결할 때 유용합니다. 예를 들어, 데이터 처리나 변환을 수행할 때 함수형 프로그래밍을 사용하면 코드가 더욱 간결하고 명확해집니다. 이를 통해 팀원 간의 협업이 쉬워지고, 유지보수성이 높아집니다. 반면, 함수형 프로그래밍을 모르면 복잡한 데이터 변환이 어려워지고, 코드가 중복되는 등의 문제가 발생할 수 있습니다.

2. 핵심 개념 설명

함수형 프로그래밍의 핵심 개념은 다음과 같습니다.

개념설명
고차 함수함수를 인자로 받거나 함수를 반환하는 함수
순수 함수동일한 입력에 대해 항상 동일한 출력을 반환하고 부작용이 없는 함수
불변성데이터가 생성된 이후 변경되지 않는 성질

예를 들어, 고차 함수는 "아이스크림 가게에서 고객이 원하는 맛을 선택하고, 선택된 맛에 따라 아이스크림을 만들어주는 것"과 비슷합니다. 고객이 원하는 맛(함수)을 입력받아 그에 맞는 아이스크림(결과)을 만들어줍니다.

3. 기본 코드 예제

아래는 고차 함수를 사용하는 기본적인 예제입니다.

#include <iostream>
#include <vector>
#include <algorithm>

// 고차 함수
std::vector<int> applyFunction(const std::vector<int>& numbers, int (func)(int)) {
    std::vector<int> result;
    for (int number : numbers) {
        result.push_back(func(number));
    }
    return result;
}

// 순수 함수
int square(int x) {
    return x  x;
}

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::vector<int> squares = applyFunction(numbers, square);
    
    for (int square : squares) {
        std::cout << square << " ";
    }
    return 0;
}

실행 결과:

1 4 9 16 25

코드 설명:

  1. applyFunction 함수는 정수 벡터와 함수를 인자로 받습니다.
  2. 빈 벡터 result를 생성하여 결과를 저장합니다.
  3. 입력된 numbers 벡터의 각 요소에 대해 인자로 받은 함수를 적용하고 결과를 result에 추가합니다.
  4. square 함수는 입력받은 정수를 제곱하여 반환합니다.
  5. main 함수에서 applyFunction을 호출하고 결과를 출력합니다.
  6. 4. 실전 활용 예제

    예제 1: 쇼핑몰에서 장바구니를 구현할 때

    #include <iostream>
    #include <vector>
    #include <numeric>
    
    double calculateTotal(const std::vector<double>& prices) {
        return std::accumulate(prices.begin(), prices.end(), 0.0);
    }
    
    int main() {
        std::vector<double> cartPrices = {19.99, 5.99, 3.50};
        double total = calculateTotal(cartPrices);
        std::cout << "총 금액: " << total << "원" << std::endl;
        return 0;
    }

    실행 결과:

    총 금액: 29.48원

    이 예제는 장바구니에 담긴 상품들의 총 금액을 계산하는 함수입니다. std::accumulate를 사용해 가격의 합을 계산합니다.

    예제 2: 리스트에서 짝수만 필터링하기

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    bool isEven(int number) {
        return number % 2 == 0;
    }
    
    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
        std::vector<int> evenNumbers;
        std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evenNumbers), isEven);
        
        std::cout << "짝수: ";
        for (int number : evenNumbers) {
            std::cout << number << " ";
        }
        return 0;
    }

    실행 결과:

    짝수: 2 4 6

    이 예제는 리스트에서 짝수만 필터링하는 방법을 보여줍니다. std::copy_if를 사용하여 조건에 맞는 요소를 새로운 벡터에 복사합니다.

    5. 흔한 실수와 주의사항

    1. 함수 포인터의 잘못된 사용

    int (*func)(int) = nullptr; // 잘못된 초기화

    올바른 코드:

    int (*func)(int) = square; // 올바르게 초기화

    주의사항: 함수 포인터를 사용하기 전에 반드시 초기화를 해야 합니다.

    2. 순수 함수의 부작용

    int globalVar = 0;
    int addToGlobal(int x) {
        globalVar += x; // 부작용 발생
        return globalVar;
    }

    올바른 코드:

    int add(int x, int y) {
        return x + y; // 부작용 없음
    }

    주의사항: 순수 함수는 부작용이 없어야 합니다.

    6. 정리

    • 함수형 프로그래밍은 코드 재사용성과 가독성을 높입니다.
    • 고차 함수, 순수 함수, 불변성 등의 개념이 중요합니다.
    • 실전에서의 활용 예제로 장바구니 계산 및 데이터 필터링을 배웠습니다.
    • 다음에 학습하면 좋은 주제는 "람다 표현식"입니다. 람다 표현식은 함수형 프로그래밍을 더 간결하게 구현할 수 있는 방법입니다.