std::function 정리

Program Lang./C++ 2017. 1. 2. 11:15

1. std::function 개요


기존 함수포인터의 개념을 확장한 것이다. c++11이후부터는 callable target이 아래와 같이 다양해졌다.

따라서 기존 함수포인터만으로는 이를 cover할 수 없고, 보다 일반화된 개념이 필요해지면서

std::function이 새롭게 나온 것이다.


std::function이 처리할 수 있는 callable target은 아래와 같다.

  • function (일반함수)
  • lambda expression
  • bind expression
  • function object (함수 객체)
  • class 내의 맴버함수 및 맴버 변수

2. usage


선언하고 사용하는 방법에 대해서 아래와 같이 정리한다.


#include <functional>

 

std::function<리턴타입(입력 파라미터들)> 변수


void print(int a, int b);

ex) std::function<void(int, int)> fp = print;

 

3. 테스트 코드


각 callable target에 대한 사용법을 예제를 통해서 알아본다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <functional>
 
using std::placeholders::_1;
 
void print_number(int i)
{
    std::cout << i << std::endl;
}
 
void print_sum(int a, int b)
{
    std::cout << a + b << std::endl;
}
 
struct PrintNum
{
    void operator()(int i) const
    {
        std::cout << i << std::endl;
    }
};
 
struct Foo
{
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};
 
int main()
{
    // 1. function (일반함수)
    std::function<void(int)> f1 = print_number;
    f1(10); // 10을 출력
     
    // 2. lambda expression
    std::function<void(int)> f2 = [](int a){ print_number(a);};
    f2(10); // 10을 출력
 
    // 3. bind expression
    std::function<void(int)> f3 = std::bind(print_sum, 10, _1);
    f3(20); // a = 10, b = 20, a + b = 30출력
     
    // 4. function object
    std::function<void(int)> f4 = PrintNum(); // 생성자호출로 함수객체 생성
    f4(10); // 10 출력, 생성된 함수객체의 operator()를 호출
     
    // 5. 객체의 맴버함수
    // 반드시 생성된 객체가 있어야 사용할 수 있다.
    const Foo foo(10); // const 맴버함수를 호출하려고 하니, const로 객체 생성
    // Foo foo(10); 의 경우로 만들때, 맴버함수의 const를 제거해야 한다.
    std::function<void(const Foo&, int)> f5 = &Foo::print_add;
    f5(foo, 10); // 20 출력
     
    // 6.1. bind + 맴버함수 경우, 생성된 객체를 참조로 넘기는 방법
    std::function<void(int)> f6 = std::bind(&Foo::print_add, &foo, _1);
    f6(10); // 20 출력
     
    // 6.2. bind + 맴버함수 경우, 생성된 객체를 복사로 넘긴다.
    std::function<void(int)> f7 = std::bind(&Foo::print_add, foo, _1);
    f7(10); // 20 출력
     
    // 6.3. 맴버변수
    std::function<int(Foo const&)> f8 = &Foo::num_;
    std::cout << f8(foo) << std::endl;
     
    return 0;
}


4. 결론

c++11 이후에서 class를 설계할 때, 기존에 함수포인터를 이용했다면 이제 std::function으로 모두

통일하는 것이 c++ 철학에 맞는 구현 방식이다.

'Program Lang. > C++' 카테고리의 다른 글

[json-c] simple generator json ojbect  (0) 2017.01.09
[json-c] simple parsing example  (0) 2017.01.09
unique_ptr, shared_ptr 읽히기  (0) 2016.12.30
c++ pair 읽히기  (0) 2016.12.30
full version (pat, pmt, sdt)  (2) 2016.07.22
: