개념

  • std::function은 호출 가능한 모든 형태를 저장, 복사, 호출할 수 있는 범용 다형성 함수 래퍼
  • 함수 포인터, 멤버 함수, 함수 객체, 람다, std::bind 표현식 등 모두 저장 가능
  • C++11에서 도입됨

함수 포인터의 한계

  • 함수 포인터는 signature가 정확히 맞아야 함
  • 멤버 함수와 일반 함수는 호출 방식이 달라 직접 관리가 불편
  • 일반 함수가 아닌 함수 객체, 람다, 지역변수를 캡처한 클로저 등은 저장 불가

정의

  template<class R, class... Args>
class std::function<R(Args...)>;
  
  • R: 반환 타입
  • Args…: 인자 타입 목록

예제

  #include <functional>
#include <iostream>
using namespace std::placeholders;

void f1(int a) {
    std::cout << "f1: " << a << '\n';
}

void f2(int a, int b) {
    std::cout << "f2: " << a << ", " << b << '\n';
}

struct Window {
    void set_width(int w) {
        std::cout << "width: " << w << '\n';
    }
};

int main() {
    std::function<void(int)> f = &f1;

    int n = 0;
    f = [](int a) {};           // 람다
    f = [n](int a) {};          // 캡처 람다

    // f = &f2; // 오류: 시그니처 불일치
    f = std::bind(&f2, _1, 0); // 바인딩 표현식으로 호환 가능

    Window w;
    // f = &Window::set_width; // 오류: 멤버 함수 주소만으로 불가
    f = std::bind(&Window::set_width, &w, _1);
}
  

내부 구조

  • std::function 객체는 내부적으로 callable target을 보관함
  • target_type(): 보관 중인 대상의 typeid 반환
  • target<T>(): 내부 객체를 포인터로 반환 (없으면 nullptr)

요약

항목설명
도입 버전C++11
가능한 대상함수, 멤버 함수, 함수 객체, 람다, 바인딩 표현식 등
사용 목적다양한 호출 가능한 대상 저장 및 실행
특징복사 가능, 타입 지워진 함수 객체, 함수 포인터보다 유연함
내부 정보 조회target_type(), target<T>() 로 타입 확인 및 참조 가능