[cpp] std::function의 예시

minjubyeon·2025년 6월 15일

cpp

목록 보기
25/26

1. std::function의 활용

🔍 std::function에는 함수의 주소를 저장해야 되는가?

정답은:

항상 함수의 주소만 저장하는 건 아니다.
"호출 가능한 모든 것"을 값처럼 저장한다.


1-1. 함수의 주소 (함수 포인터) 저장 가능

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

std::function<void(int)> fn = hello;  // 함수 이름만 쓰면 주소로 변환됨
  • 이건 맞아요. 함수 포인터를 저장한 거예요.
  • 이 경우 hello는 정적인 주소가 있는 함수니까 OK

1-2. 람다 함수 저장 가능

std::function<void(int)> fn = [](int x) ⚠️{
    std::cout << "lambda: " << x << '\n';
};
  • 이건 주소가 아니라 함수 객체(function object)를 저장하는 것
  • 내부에서 캡처가 있다면, std::function복사해서 저장하고,
    필요 시 힙에 동적 메모리 할당까지 함

1-3. 클래스의 멤버 함수도 저장 가능

std::function<void(const A&)> fn = &A::show;⚠️
  • 이것도 함수 주소지만, 멤버 함수 주소는 일반 함수와 다르게
    객체가 필요함 → 그래서 fn(a)처럼 객체를 전달해야 실행 가능



2. 🔍 &는 언제 사용하는가?

✅ 예시 2와 예시 3 모두 "함수 객체"를 저장하는 건데,
👉 왜 **예시 2 (람다)**는 & 없이 저장하고
👉 예시 3 (&A::show)은 & 붙여야 하느냐?

⚡ 핵심 결론부터 말하면:

람다 자체는 객체이기 때문에 & 필요 없음
&A::show"함수" 그 자체의 주소이기 때문에 &가 꼭 필요함


📦 예시 2: 람다

std::function<void(int)> fn = [](int x) {
    std::cout << "lambda: " << x << '\n';
};
  • [](int x){ ... } 는 람다 "객체"입니다.
  • 즉, 이 코드는 struct Lambda { void operator()(int) const {...}; } 를 만든 것과 같아요.
  • 그래서 그냥 "값"으로 넘길 수 있습니다.
  • 👉 & 필요 없음

📦 예시 3: 클래스의 멤버 함수

std::function<void(const A&)> fn = &A::show;
  • &A::showA 클래스 안의 멤버 함수 주소입니다.
  • 즉, 아직 A 객체는 없음!
  • show는 객체 없이 호출할 수 없는 멤버 전용 함수니까
    &가 있어야 그 함수의 위치(주소)를 std::function이 알 수 있어요.

⚠️ 왜 헷갈리는가?

람다도 결국 operator()를 가진 객체니까 클래스처럼 생겼는데,
&람다::operator() 없이 그냥 쓰는 거냐?

람다는 이미 객체이고, 그 자체가 호출 가능(callable)한 값이에요.
하지만 A::show는 "코드"일 뿐, 객체 없이 실행할 수 없어요.


🧠 정리표

표현의미& 필요 여부
[](int x){...}람다 객체
Print()함수 객체
hello일반 함수 → 주소로 변환됨보통 ❌
&A::show멤버 함수 주소✅ 반드시 필요

⚠️ 정리: 반드시 주소만 저장하는 게 아니다!

저장 대상저장 방식
일반 함수함수 포인터 (주소) 저장
람다 (캡처 없음)함수 포인터처럼 동작
람다 (캡처 있음)객체를 복사해서 저장 → 힙 할당 가능성
함수 객체 (클래스)operator()를 가진 객체 저장
멤버 함수 주소특별한 포인터 형식으로 저장됨

🔚 결론

std::function객체(람다/클래스) 를 넘길 땐 & 안 붙여도 되고
멤버 함수나 일반 함수처럼 주소를 넘길 땐 &가 필요해요.



profile
안녕하세요.

0개의 댓글