PHpullh

C++ · 심층 가이드

C++ 함수형 완전 정리

optional과 variant, ranges를 활용한 15개 예제로 순수 함수, 불변 업데이트, 지연 파이프라인을 C++ 문법 안에서 구성합니다.

주제 15개 · 예제 코드 포함 · 최종 수정 2026-08-30 · 작성 pullh 편집팀

함수형 스타일이 C++에 들어온 방식은 조금 특이합니다. 값 의미론이 원래부터 강한 언어라 불변 데이터는 자연스러운데, 대신 값을 복사하는 비용이 눈에 보입니다. 그래서 여기서의 관심사는 "부작용을 없애는가"보다 "불필요한 복사 없이 부작용을 격리하는가"에 가깝습니다. std::optionalstd::variant가 합타입 역할을 맡고, 파이프라인은 ranges의 뷰가 담당하는 식으로, 기존 문법 위에 얹히는 모양입니다.

순수 함수불변 업데이트로 값 의미론을 확인한 다음, Maybe 스타일 처리Result 스타일 매핑에서 실패를 값으로 다루는 방법으로 넘어가면 흐름이 끊기지 않습니다. compose, partial 적용, curried 함수는 앞의 함수 편과 이어지는 세 항목이라 묶어서 보는 편이 낫고, lazy iteratorpipeline은 중간 컨테이너를 만들지 않는다는 점에서 성능 편의 스트리밍 주제와도 맞닿아 있습니다.

지연 평가에는 대가가 따릅니다. ranges의 뷰는 원본을 소유하지 않으므로, 임시 컨테이너를 반환하는 함수 결과에 뷰를 붙여 두고 나중에 순회하면 이미 사라진 데이터를 읽게 됩니다. 뷰는 만든 자리에서 소비하거나 결과를 컨테이너로 물질화해 두는 편이 안전합니다. std::optional도 마찬가지로, 값이 없는 상태에서 *->로 접근하면 검사 없이 정의되지 않은 동작이 됩니다. 예외를 원한다면 value(), 기본값을 원한다면 value_or()로 의도를 분명히 적어야 합니다.

01순수 함수

C++에서 순수 함수 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// 순수 함수
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 1};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

02불변 업데이트

C++에서 불변 업데이트 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// 불변 업데이트
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(20.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

03Maybe 스타일 처리

C++에서 Maybe 스타일 처리 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// Maybe 스타일 처리
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 3};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

04Result 스타일 매핑

C++에서 Result 스타일 매핑 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// Result 스타일 매핑
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(40.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

05fold 합계

C++에서 fold 합계 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// fold 합계
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 5};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

06compose

C++에서 compose 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// compose
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(60.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

07partial 적용

C++에서 partial 적용 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// partial 적용
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 7};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

08curried 함수

C++에서 curried 함수 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// curried 함수
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(80.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

09pipeline

C++에서 pipeline 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// pipeline
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 9};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

10lazy iterator

C++에서 lazy iterator 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// lazy iterator
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(100.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

11패턴 분기

C++에서 패턴 분기 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// 패턴 분기
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 11};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

12reducer 상태 누적

C++에서 reducer 상태 누적 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// reducer 상태 누적
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(120.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

13all predicate

C++에서 all predicate 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// all predicate
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 13};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

14flatMap

C++에서 flatMap 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// flatMap
#include <iostream>

int main() {
    auto add_tax = [](double price) { return price * 1.1; };
    std::cout << add_tax(140.0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

15함수 값을 반환하는 함수

C++에서 함수 값을 반환하는 함수 개념을 코드로 빠르게 확인하는 함수형 예제입니다.

C++ code

// 함수 값을 반환하는 함수
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> values = {1, 2, 3, 15};
    std::cout << std::accumulate(values.begin(), values.end(), 0) << "\n";
}
알아두면 좋은 점

함수형 예제는 입력과 출력이 분명할수록 재사용과 테스트가 쉬워진다는 점이 핵심입니다.

자주 하는 실수

원본 데이터를 직접 바꾸기 시작하면 함수형 스타일의 장점이 크게 줄어듭니다.

정리하며

  • ranges 뷰는 원본을 소유하지 않으므로 임시 객체에 붙인 채 보관하면 안 됩니다
  • 빈 optional에 * 접근은 정의되지 않은 동작이고, value()는 예외를 던집니다
  • 실패를 예외 대신 optional이나 variant 값으로 표현하면 호출부 흐름이 단순해집니다
  • 파이프라인을 뷰로 구성하면 중간 컨테이너 할당 없이 한 번의 순회로 끝납니다

더 깊이 들어가고 싶다면 C++ 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.