In this post, our journey through the functional features of classical, modern, and future C++ continues. Today, we stop in the present.
What has modern C++ to offer?

In 2005, 13 libraries based on Boost, were proposed in the so called technical report 1 (TR1) as candidates for the upcoming C++ standard. 12 of them made it into C++11 including the two functions std::bind and std::function. Both functions work very well together. On one hand, std::bind empowers you to easily make function objects. At the other hand, std::functions gets this temporary function objects from std::bind and gives them a name. Both functions need the header <functional>. You can guess, why.
std::bind
You can generate with std::bind function objects in various ways, because it empowers you to
- bind the argument at arbitrary positions,
- reorder the sequence of the arguments,
- introduce placeholders for arguments,
- partially evaluate functions,
- and directly invoke the new function object, use it in the algorithm of the Standard Template Library (STL), or store it in std::function.
std::function
std::function is a polymorphic function wrapper. Therefore, it can take arbitrary callables and give them a name. Callables are all entities which behave like a function. In particular, these are lambda-functions, function objects, and functions themselves. std::function is always needed, if you have to specify the type of a callable.
That was enough theory. Lets starts with the more interesting stuff.
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
|
// bindAndFunction.cpp
#include <functional>
#include <iostream>
double divMe(double a, double b){
return double(a/b);
}
using namespace std::placeholders;
int main(){
std::cout << std::endl;
// invoking the function object directly
std::cout << "1/2.0= " << std::bind(divMe, 1, 2.0)() << std::endl;
// placeholders for both arguments
std::function<double(double, double)> myDivBindPlaceholder= std::bind(divMe, _1, _2);
std::cout << "1/2.0= " << myDivBindPlaceholder(1, 2.0) << std::endl;
// placeholders for both arguments, swap the arguments
std::function<double(double, double)> myDivBindPlaceholderSwap= std::bind(divMe, _2, _1);
std::cout << "1/2.0= " << myDivBindPlaceholderSwap(2.0, 1) << std::endl;
// placeholder for the first argument
std::function<double(double)> myDivBind1St= std::bind(divMe, _1, 2.0);
std::cout<< "1/2.0= " << myDivBind1St(1) << std::endl;
// placeholder for the second argument
std::function<double(double)> myDivBind2Nd= std::bind(divMe, 1.0, _1);
std::cout << "1/2.0= " << myDivBind2Nd(2.0) << std::endl;
std::cout << std::endl;
}
|
Do you want to see a few variations of invoking divMe (line 6 - 8). In order to use the simple notation _1, _2 for the placeholders std::placeholders::_1, std::placeholders::_2 in the source code, I have to introduce the namespace std::placeholders in line 10.
I bind in line 17 in the expression std::bind(divMe, 1, 2.0) the arguments 1 and 2.0 to the function divMe and invoke them in place with (). I bind in line 20 the function object and invoke it with the arguments 1 and 2.0. Line 24, 28, and 32 follows a similar strategy. I change the sequence of the arguments in line 24. In line 28, only the first argument is bound; in line 32, only the second argument. std::function gets the resulting function objects. Template arguments like double(double, double) (line 24) or double(double) (line 28 and 32) stands for the type of the callable, which std::function accepts. double(double, double) is a function taking two doubles and returning a double.
At the end, the output of the program.

Impressed? I guess, yes. In particular, the last two examples in which std::function gets a function of arity two and returns a function of arity one is quite astonising. The arity of a function is the number of arguments a function gets. std::bind evaluates in both calls only one argument and uses for the non-evaluated one a placeholder. This technique is called partial function application.
Partial function application
Partial function application is quite similar to a technique called currying. Currying is well known in functional programming. It stands for a technique in which a function taking more than one argument will successively be transformed in series of function taking only one argument. Therefore, there are in programming language Haskell only functions taking one argument. I hear your question. How is it possible to implement a function such as add which needs two arguments. The magic is happening implicitly. Functions in Haskell, that needs n arguments are transformed in functions returning a function, which only needs n-1 arguments. The first elements is evaluated in this transformation.
The name currying is coined by the mathematician Haskell Curry and Moses Schönfinkel. Currying is named after the family name of Haskell Curry; Haskell after his first name. Sometimes, currying is called schönfinkeln.
A drop of bitterness
A drop of bitterness remains. As well std::bind as std::function are almost superfluous with C++11. You can use lambda-functions instead of std::bind, you can use most of the times automatic type deduction with auto instead of std::function. With the enriched core language in C++11, we can quite easily rewrite the program.
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
|
// lambdaAndAuto.cpp
#include <functional>
#include <iostream>
double divMe(double a, double b){
return double(a/b);
}
using namespace std::placeholders;
int main(){
std::cout << std::endl;
// invoking the function object directly
std::cout << "1/2.0= " << [](int a, int b){ return divMe(a, b); }(1, 2.0) << std::endl;
// placeholders for both arguments
auto myDivBindPlaceholder= [](int a, int b){ return divMe(a, b); };
std::cout << "1/2.0= " << myDivBindPlaceholder(1, 2.0) << std::endl;
// placeholders for both arguments, swap the arguments
auto myDivBindPlaceholderSwap= [](int a, int b){ return divMe(b, a); };
std::cout << "1/2.0= " << myDivBindPlaceholderSwap(2.0, 1) << std::endl;
// placeholder for the first argument
auto myDivBind1St= [](int a){ return divMe(a, 2.0); };
std::cout<< "1/2.0= " << myDivBind1St(1) << std::endl;
// placeholder for the second argument
auto myDivBind2Nd= [](int b){ return divMe(1, b); };
std::cout << "1/2.0= " << myDivBind2Nd(2.0) << std::endl;
std::cout << std::endl;
}
|
Let me say a few words about the lambda-functions. The expression [](int a, int b){ return divMe(a, b); }(1, 2.0) defines a lambda-function that executes divMe. The trailing braces invoke the lambda-function just in place. This will not hold for the lambda-functions in line 28 and 32. Both will be invoked in the subsequent lines. The impressing fact is that the lambda-function binds the first (line 32) or the second argument (line 28).
What's next?
The polymorph function wrapper std::function can most of the times be replaced by auto. Most of the times because sometimes you have the explicitly specify the type of the callable. That is the domain of std::function. A typical example for such a use case is a dispatch table which I will present in the next post.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Darshan Mody, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Wolfgang Gärtner, Louis St-Amour, Stephan Roslen, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Avi Kohn, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, and Peter Ware.
Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, and Sudhakar Belagurusamy.
Seminars
I'm happy to give online-seminars or face-to-face seminars world-wide. Please call me if you have any questions.
Bookable (Online)
Deutsch
English
Standard Seminars
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
New
Contact Me
Modernes C++,

Comments
I am actually enjoying by these.
come with approximately all significant infos.
I would like to peer extra posts like this .
RSS feed for comments to this post