std::bind and std::function overlap or complementary? - c++

I was looking at this exemple here, combining std::bind and std::function so as to create a command: really neat! The code for the command class goes like this:
class Command
{
private:
std::function<void ()> _f;
public:
command() {}
command(std::function<void ()> f) : _f(f) {}
template <typename T> void setFunction (T t) {_f = t ;}
void execute()
{
if(!_f.empty())
_f();
}
};
Assuming I have a class MyClass containing a member function:
class MyClass
{
public:
void myMemberFn() {}
}
Then the calling code looks like:
MyClass myClass;
command(std::bind(&MyClass::myMemberFn, myClass));
Though I must admit I do not really understand why std::function is needed in addition to std::bind. It seems to me that bind already encapsulates the function call, so why is function needed in Command? Couldn't Commandstore a std::bind rather than a std::function?
I have been looking at documentation for both std::bind and std::function and did not get it...
Anyone has an idea of why std::functionis needed?
PS: I am assuming std::bind ~= boost::bind and std::function ~= boost::function

You have to store the result of the std::bind expression somewhere. The return type of std::bind itself is unspecified by the standard, so you cannot create a named member variable of that type (you can use the C++11 auto to create such a local variable, though!)
Also, any function taking std::function can (due to std::function implicit conversions) accept all sorts of callable objects, not just std::bind results - you can pass it a regular function pointer, a lambda, a custom function object, whatever that can be invoked.

From the bind documnentation,
A function object of unspecified type T, for which std::is_bind_expression<T>::value == true,
and which can be stored in std::function.
So
std::function<void ()> _f;
is needed to store the return value of
command(std::bind(&MyClass::myMemberFn, myClass));
so that this can be actually invoked later.

Related

using the 'this' pointer inside a std::function prototype

to my understanding a member function is different to a normal function because there is an additional this pointer parameter.
So my idea is to make is make the following member template function to one of my classes:
template <class T>
void ApplyFunction(function<void(vector<int>&, T)> fun, T val);
and then I will use it inside one of my classes like:
Thing.ApplyFunction(myMethod, this);
and Thing will use the myMethod from my current class instance.
A lot of this code is guesswork so I would like some clarification as to if this would work. Also not sure which way round it is:
void ApplyFunction(function<void(vector<int>&, T)> fun, T val);
or
void ApplyFunction(T val, function<void(vector<int>&, T)> fun);
A code sample describing why I might want something like this:
void ClassA::callbackMethod(vector<int> &array)
{
//I can edit the array here
}
void ClassA::someMethod(void)
{
ClassB B;
B.ApplyFunction(callbackMethod, this);
//now whenever B wants to edit the array, it can by using callbackMethod
B.ComplicatedStuff(); // B uses the callbackMethod multiple times here
}
It looks to me like you are just planning to invoke a method, and you don't need to store the callable. If that is the case you should not use std::function but simply take a callable as a template parameter.
template <class T>
void ApplyFunction(T&& func) {
func(/*pass in your vector here*/);
}
With that you can you can then call it from A by passing in a lambda.
void ClassA::someMethod(void)
{
ClassB B;
B.ApplyFunction([&](std::vector<int>& vec){
// do stuff with vec here
// or call a member function
callbackMethod(vec);
vec.push_back(2);
});
}
This will be faster since passing by template parameter like this gives almost no additional cost from just a normal function call. If the function is inline it can be as cheap as just calling a member function.
std::function is a type-erased wrapper for any callable and comes with overhead, only use it if you need to store the callable for later use.
Edit
If you like to store the function, you don't need a template, you can simply take a std::function as parameter in ApplyFunction.
void ApplyFunction(std::function<void(std::vector<int>&)> func) {
//Store it, call it now or call it later.
m_func = func;
m_func(/*pass in your vector here*/);
}
Call it the same way, with a lambda.
Using a lambda like this is the preferred method when binding a member function to an instance. Instead of passing this separately it's better to wrap it in a lambda and get it for free so to speak.

How to pass reference to function with lambda

I have a data member that is of type:
std::function<T(T&, T&)>&
The constructor accepts an argument of the same type.
How should I send such a function using lambdas?
I've tried
MyClass tmp([](Foo &a, Foo &b) { return a+b; }, ...);
But it fails.
For example:
main.cpp
#include "MyClass.h"
int main()
{
MyClass a([](int x, int y) { return x+y;});
return 0;
}
MyClass.h
#pragma once
#include <functional>
class MyClass
{
public:
MyClass(std::function<int(int, int)>&) noexcept;
private:
std::function<int(int, int)>& fun;
};
You are passing a lambda to a std::function &. A lambda is not a std::function so that doesn't work directly. However, a lambda is convertible to a std::function, so a temporary std::function has to be build that holds the lambda.
Since you are taking a std::function & C++ assumes you want to modify that value, otherwise there would be no point in taking it by non-const reference. Modifying a temporary has no effect, so this doesn't make sense, so C++ doesn't allow it.
One way to fix the issue is to take a const std::function &. That way there is no modifying of a temporary.
Another way is to pass an actual std::function that you create in main.
Another way is to create a template that just forwards it's argument to the std::function:
class MyClass
{
public:
template <class T>
MyClass(T &&t)
: fun(std::forward<T>(t)){}
private:
std::function<int(int, int)> fun;
};
That way MyClass takes anything and uses it to construct fun. Note that fun is not a reference anymore. The std::function has to live somewhere and since it is part of MyClass it makes sense to tie the lifetime of the std::function to MyClass.
If you really want fun to be a reference you need to find a place for it and make sure it stays there until after MyClass a; gets destroyed. I do not recommend this route since it gets increasingly difficult to make sure the lifetimes are correct.
You can also store the lambda directly, but that is a bit tricky and depending on what you actually want to do with MyClass it may not be viable.

c++ using method as parameters to functions

I don't understand why the following code compile and works:
template<typename Predicate>
void foo(Predicate p) {
}
bool g(int n) {
}
void user(int n) {
foo(g);
}
foo is supposed to get a function object that will run on a data structure but I made the method simpler, because what I don't understand is how can this works? A method isn't an object. The normal way to do it is to create a new class, override operator() and then send an instance of that class.
Well, in this case the Predicate parameter is substituted by a function pointer of type bool (*func) (int). Nothing wrong with that...
The Predicate template argument can be almost any type. So you can use it for function pointers and classes as well as the basic types.
If you use the function argument p as a function, then it can be anything that is callable, like a function pointer, an object whose class have an operator() member function, a pointer to a static member function, a std::bind object, a std::function object or a lambda expression.
It can't be a pointer to a member function though, because to call a pointer to a member function you need an instance to call it on. For this use std::bind.

how to make std::function instance

In C++0x, we use use std::function like the following:
int normal_function() {
return 42;
}
std::function<int()> f = normal_function;
So to get an std::function instance, we have to define its type firstly. But it's boring and sometimes hard.
So, can we just use make to get a std::function instance just like std::tuple?
In fact, I just googled, C++0x doesn't provide such make facility.
Why C++0x no provide make facility?
Can we implement it?
Yes we can implement it
template<typename T>
std::function<T> make_function(T *t) {
return { t };
}
This requires that you pass a function to make_function. To prevent overload to pick this up for something other than a plain function, you can SFINAE it
template<typename T>
std::function<
typename std::enable_if<std::is_function<T>::value, T>::type
> make_function(T *t) {
return { t };
}
You cannot pass it class type function objects though and no member pointers. For arbitrary function objects there is no way to obtain a call signature (what would you do if the respective operator() is a template?). This probably is the reason that C++11 provides no such facility.

How do you pass boost::bind objects to a function?

I have a one-dimensional function minimizer. Right now I'm passing it function pointers. However many functions have multiple parameters, some of which are held fixed. I have implemented this using functors like so
template <class T>
minimize(T &f) {
}
Functor f(param1, param2);
minimize<Functor>(f);
However the functor definition has lots of crud. Boost::bind looks cleaner. So that I could do:
minimize(boost:bind(f,_1,param1,param2))
However I'm not clear what my minimize declaration should like like using boost::bind. What type of object is boost::bind? Is there an easy pattern for this that avoids the boilerplate of functors but allows multiple parameter binding?
You can just use boost::function. I think boost::bind does have its own return type, but that is compatible with boost::function. Typical use is to make a typedef for the function:
typedef boost::function<bool(std::string)> MyTestFunction;
and then you can pass any compatible function with boost::bind:
bool SomeFunction(int i, std::string s) { return true; }
MyTestFunction f = boost::bind(SomeFunction, 42, _1);
f("and then call it.");
I hope that is what you want.
It also works with methods by passing the this pointer for the call as second parameter to boost::bind.
I would define minimize() this way:
minimize(boost::function< return_type(param_type1,param_type2,param_type3,...)> f)
{
...
}
Then you could call minimize() like this:
minimize(boost::bind(&class::function,actual_object,_1,_2,_3,...));
Change the parameter to a value parameter. Function objects are intentionally light weight, and boost::bind certainly is, specially crafted to fit in within space of a few bytes using boost::compressed_pair and what not.
template <class T>
void minimize(T f) {
}
Then you can pass it the result of boost::bind. Remember that boost::bind is actually a function template that returns some object of some type. So having minimize have a non-const reference parameter couldn't work.
First, you are taking your template argument as a ref-to-non-const, so the temporary returend by boost::bind won't bind to it. So you can use it like:
template <class T>
T::result_type minimize(const T &f) {
}
But if you wanted to use this with your Functors as well, they would have to have a const operator(). So perhaps by value is better:
template <class T>
T::result_type minimize(T f) {
}
I believe having the return be T::result_type will force a T to be a boost::function (rather than the complicated type bind returns), but I'm not 100%