C++11 Lambda expressions, std::function,std::bind and callbacks

Introduction : Lambda expressions in C++11 produce function objects (functors) behind the scenes, which are very useful when working with STL algorithms since they can store state compared to normal functions. You can simplify writing function objects greatly by using lambda expressions. At the end of this post, will share a callback implementation.

It should be noted that , previous STL algorithm related features are deprecated in C++11 :

Function object base classes : std::unary_function , std::binary_function
Adapters for class members : mem_fun, ptr_fun ( Replacement is std::mem_fn )
Binder classes : bind_1st, bind_2nd ( Replacement is std::bind and std::placeholders )

Lambda syntax is like :

[]() { } // barebone lambda [/code]

[] : capture list
() : arguments
{} : body

Additionally if you want to specify the return type :

[](double d) -> double { double x =0; return x; };

Examples :

1. Usage with STL algorithms as “nameless functions” :

In simple cases , the return type will be deduced :

2. Variable initialisation :

3. Named nested functions : You can assign lambda expressions to C++11 autos :

Capture lists : You can capture by both reference and value, which you can specify using = and &:

[&variable_name] capture by reference
[&, variable_name] specify that the default way of capturing is by reference and what we want to capture
variable_name by value
[=, variable_name] capture by value by default, but for variable_name use reference instead


Constness and mutable : Lambda expressions are const by default. However you can use the keyword mutable to change that.

std::function : std::function is a template class in header. It can store all “callable” objects :

– functions
– functors
– class methods
– lambda expressions

For an example, let`s first implement a simple class called SimpleCallback which has std::function member that can store “callable” objects with void return value and no arguments :

Now let`s see that class in use :

std::bind & std::placeholders : std::bind functions receives a lambda function/function pointer/functor and returns std::function object. Its main use is binding parameters to std::function objects.

On the other hand, by using std::placeholders , you can bind parameters to different places :

As a final note about binding parameters to std::function , std::bind works with copy-by-value. Therefore if one of function arguments is a reference, you need to use a template function std::ref which returns an object of std::reference_wrapper :

std::ref : You can use std::ref to generate std::reference_wrappers in order to bind parameters by reference. Finally std::mem_fn can be used to point to class members and methods.

When you can use lambda expressions : I have listed some use cases :

    1. To write one-liners in with std::algorithm , particularly std::for_each
    2. Small functionalities in source code ,when you don`t prefer to promote a code snippet to be a function
    3. In places where you need to pass a function object. A good example is std`s condition variables.
    4. I have found them pretty useful when writing unit test code for testing thread safe containers as it is very convenient to use std::thread with them.
    5. Another good place to use them is specifying custom deleters with std smart pointers :

Example class ( FileWatcher ) : I will share an example implementation which is a class that watches changes to a text file. In order to use you have to register your callbacks. The class uses std::function :

Finally in order to use it :

class Foo {…};

void Foo::fileChangeCallback(const std::string& fileName, const std::vector& changedLines)
{

}

std::string fileName =”dummy.txt”;
std::unique_ptr watcher(new FileWatcher(fileName, std::bind(&Foo::fileChangeCallback, this, std::placeholders::_1, std::placeholders::_2)));

Advertisements

1 thought on “C++11 Lambda expressions, std::function,std::bind and callbacks”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s