[cpp] std::function

minjubyeon·2025년 6월 15일

cpp

목록 보기
24/26

1. std::function

std::function은 C++ STL에서 제공하는 함수 래퍼(wrapper)로,
함수, 람다, 함수 객체, 멤버 함수 포인터 등 다양한 호출 가능한(callable) 것을 하나의 타입으로 다룰 수 있게 해주는 템플릿 클래스입니다.


📌 정의 (슬라이드 351 참고):

template<class R, class... Args>
class std::function<R(Args...)>;
std::function<void(int)>

“정수 하나를 받고 반환값이 없는 함수”를 저장할 수 있는 타입이라는 의미입니다.


📦 예시

#include <iostream>
#include <functional>

void hello(int x) {
    std::cout << "Hello " << x << '\n';
}

int main() {
    std::function<void(int)> fn = hello;
    fn(10);  // Hello 10
}

💡 상황

std::function<void(int)> fn = hello;

이 문장에서 핵심은 두 부분입니다:

  1. std::function<void(int)> fn
    → "정수 하나를 받고 아무것도 반환하지 않는 함수 타입"을 저장할 수 있는 변수 fn을 선언함.

  2. = hello
    hello라는 일반 함수를 fn에 넣는다(저장한다)는 의미.


🔍 '함수를 저장한다'는 건 무슨 뜻인가?

C++에서 std::function함수를 값처럼 다룰 수 있게 해주는 도구입니다.

아래는 예시 비교입니다:

내용비유
int x = 5;x에 5를 저장
std::function<void(int)> fn = hello;fn에 hello 함수를 저장

즉, fn이라는 변수는 hello 함수를 기억하고 있다가, 나중에 그걸 대신 실행해주는 거예요.


📦 비유를 통한 예시

void hello(int x) {
    std::cout << "Hello " << x << '\n';
}

이건 하나의 기능(기계)이고,

std::function<void(int)> fn = hello;

이건 그 기능을 fn이라는 리모컨에 저장한 거예요.

이제 fn(10); 이라고 호출하면,
리모컨이 hello(10)을 대신 눌러주는 겁니다.


🔚 결론

  • std::function<void(int)> fn = hello;
    👉 hello라는 함수의 주소(실행 방법)fn이 저장한 것

  • fn(10);
    👉 hello(10)간접적으로 호출한 것


필요하면 fn에 다른 함수나 람다도 넣을 수 있어요:

fn = [](int x) { std::cout << "Lambda " << x << '\n'; };
fn(20);  // Lambda 20



🔍 왜 std::function을 써야 할까?

함수 포인터는 아래처럼 고정된 함수만 받을 수 있습니다:

void (*fp)(int);

하지만 std::function<void(int)>은 아래 모두 가능:

  • 일반 함수
  • 캡처 없는 람다 [](int x){ ... }
  • 캡처 있는 람다 [=](int x){ ... }
  • 함수 객체 struct Op { void operator()(int); };

✅ 장점

  • 함수 포인터처럼 함수만 받는 것이 아니라
    람다식, 클래스의 멤버 함수, 함수 객체도 받을 수 있음
  • 다양한 호출 방식을 하나의 타입으로 통일해서 넘기기 편함

❌ 단점

  • 내부적으로 type erasure를 하므로 약간 느릴 수 있음
  • 복잡한 람다/객체를 저장하면 동적 메모리 할당 발생 가능

⚠️ 차이점 (일반 함수 vs std::function)

void (*f)(int);          // 단순 함수 포인터만 가능
std::function<void(int)> // 무엇이든 호출 가능한 객체면 됨

🔚 결론

std::function은 "모든 호출 가능한 것"을 저장하는 다형적 함수 타입 래퍼입니다.
람다 함수와 함께 쓰는 게 대표적인 활용법이에요.
포인터보다 훨씬 유연하지만 약간 무거움도 함께 기억하세요.




profile
안녕하세요.

0개의 댓글