C++ General-Purpose Polymorphic Function Wrapper

Introduction

C++ class template std::function is a general-purpose polymorphic function wrapper. It could wrap functions, functors, and lambda expressions allowing them to use the same argument type in the higher-order function.

In this blog post, I would like to show how to use std::function.

Examples

std_function.cpp
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <functional>
#include <iostream>

template <typename T>
T add(T x, T y)
{
return x + y;
}

template <typename T>
T minus(T x, T y)
{
return x - y;
}

template <typename T>
T runBinaryFunction(T x, T y, std::function<T(T, T)> f)
{
return f(x, y);
}

template <class T>
class Add
{
public:
T operator() (T x, T y) const
{
return x + y;
}
};

template <class T>
class Calculator
{
public:
static T add(T x, T y)
{
return x + y;
}
};

template <class T>
class Increase
{
public:
Increase(T val) : mVal{val}
{
}
T increase(T x) const
{
return x + this->mVal;
}
private:
T mVal;
};

int main()
{
int x = 1;
int y = 2;

// Wrap functions
std::function<int(int, int)> f1 = add<int>;
std::cout << f1(x, y) << std::endl;
std::cout << runBinaryFunction(x, y, f1) << std::endl;

// Wrap functors
std::function<int(int, int)> f2 = Add<int>();
std::cout << f2(x, y) << std::endl;
std::cout << runBinaryFunction(x, y, f2) << std::endl;

// Wrap lambda expressions
std::function<int(int, int)> f3 = [](int x,int y)->int{return x + y;};
std::cout << f3(x, y) << std::endl;
std::cout << runBinaryFunction(x, y, f3) << std::endl;

// Wrap class methods
std::function<int(int, int)> f4 = std::bind(&Calculator<int>::add, std::placeholders::_1, std::placeholders::_2);
std::cout << f4(x, y) << std::endl;
std::cout << runBinaryFunction(x, y, f4) << std::endl;

Increase<int> increaseTen(10);
std::function<int(int)> f5 = std::bind(&Increase<int>::increase, increaseTen, std::placeholders::_1);
std::cout << f5(x) << std::endl;
}

To compile the program, please run the following command in the terminal.

1
$ g++ std_function.cpp -o std_function -std=c++11

Conclusions

std::function is highly polymorphic, general-purpose, and versatile. So there will be significant runtime overhead. However, because it is so general-purpose, it is often used in the C++ callback interface so that the user could pass different kinds of callable implementations.

C++ General-Purpose Polymorphic Function Wrapper

https://leimao.github.io/blog/CPP-std-function/

Author

Lei Mao

Posted on

02-11-2020

Updated on

02-27-2022

Licensed under


Comments