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

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%

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.

std::forward and ref-qualifiers for member functions

I was in a position where I was using std::forward wherever I had a forwarding reference and I was wondering if some of that was unnecessary or even wrong. For example having std::forward in a std::begin() call.
Because of the ability of a class being able to overload its member functions based on whether the call is made with the object as an rvalue or not https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/, I assumed that a templated function would be as efficient as possible if you were knew that the inner function you were forwarding the object to was non-mutating and/or was a member function of the object. For example
template <typename Something>
void do_something(Something&& something) {
std::forward<Something>(something).do_something();
auto iter = std::begin(std::forward<Something>(something));
for_each(iter, std::end(std::forward<Something>(something), []() {});
}
I saw this question (When not to use std::forward with r-values?) but it did not address the member function ref-qualifiers and it also did not clearly address what the best practice is when you don't have access to the inner functions definitions that you are calling.
Is there a general guideline for when not to use std::forward that addresses the things I mentioned? Or is there some key concept that I am missing?
Except if you know the type you will have, avoid to use std::forward several time in the same function for the same object, as the second time, your object might be moved.
// assuming implementation which really need pass by value instead of const reference
template <typename T> void pass_by_value(T t) { std::cout << t; }
template <typename T>
void foo(T&& t)
{
pass_by_value(std::forward<T>(t));
pass_by_value(std::forward<T>(t));
}
a call of foo with std::string
foo(std::string("Hello world")); // or "Hello world"s
might call the equivalent to
pass_by_value(std::string("Hello world"));
pass_by_value(std::string("")); // Moved string...
The problem is a use after object moved from ("stealed"). If something used in a multiple lines of do_something, then use std::forward only at the last such line to prevent the problem.

std::bind and std::function overlap or complementary?

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.

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.

C++ Pointer to a function which takes an instance of a templated class as argument

I have trouble compiling a class, which has function pointers as member variables. The pointers are to functions which take an instance of a class as argument.
Like
template<class T, int N>
double (*f)(Vector<T,N> v);
I get "error: data member 'f' cannot be a member template" Compiler is gcc 4.2.
Edit
Before using templates I just had
double (*f)(Vector v);
This also works
double (*f)(Vector<double,2> v)
But I would like to have a function pointer for a function which takes a generic Vector as argument..
Use a member typedef:
template <typename T, int N>
class Vector
{
public:
/// type of function pointer
typedef double (*FuncPtr)( const Vector& );
};
// concrete type
typedef Vector<double,10> VecDouble10;
// actual function
double func( const VecDouble10>& );
// usage
VecDouble10::FuncPtr fp = func;
If you want to have a "template pointer", you could try a function object. The example below adds 1.0 to the wrapped function template.
struct AcceptsVector {
template<typename T, int N>
double operator()(Vector<T,N> v) const { return 1.0 + real_f(v); }
};
AcceptsVector f;
The difference to a "real" template pointer is that you cannot re-seat "AcceptsVector" to call another template, like you can do with normal function pointers. The binding is hardcoded at compile-time. However you can pass along f like a function pointer, and can call f with any Vector<T, N> like a template.
That isn't quite valid c++, basically what you're looking for are template-template parameters.
http://www.progdoc.de/papers/ttp/psi-ttp/psi-ttp.html
explains all about them
Generally, if you get yourself into this situation, you want to find a workaroumd, because your code becomes illegible VERY quickly
Well, the compiler doesn't know at the compile time, how many f's are you going to have (one for each possible T and N?). Therefore the compiler cannot calculate how much memory do objects of your class need. That's why such constructs are prohibited.
You can't have a templated pointer to function, that makes no sense.
But what you can do is
#include <vector>
template <typename T>
void foo(const std::vector<T>& v) {
// do something
}
void (*ptr_foo)(const std::vector<int>&) = &foo<int>;
(here the function pointers a templated function, which template argument is explicitly set to int)
Because your code makes just as much sense as:
struct X
{
template < typename T >
std::vector<T> vect;
};
You're trying to make a member variable a template. This is just not a valid C++ construct and I seriously doubt it ever will be.
How do you do what you actually want? I'm not sure since I don't know what you actually are trying to accomplish and why.