std::function<> is a useful wrapper around almost any callable thing, including free functions, lambdas, functors, member functions, results from st
As commented here and elsewhere, there is the ambiguity issue that can confuse type inferencing. Probably these corner cases stopped a std::make_function from being adopted as it would not be able to resolve ambiguity, overloading or work nicely with C++ automatic type conversions. Another argument against it that I see a lot is that std::function has overhead (in type erasure), and many people are against using std::function on that basis for anything other than storage of callables.
However, for the non-ambiguous case, it is possible to write a make_function for lambdas and other callables that takes care of type inferencing, which avoids repeating function type signatures when there is really no ambiguity. One way to do it (taken from my related question) is as follows:
#include
#include
#include
#include
using namespace std;
// For generic types that are functors, delegate to its 'operator()'
template
struct function_traits
: public function_traits
{};
// for pointers to member function
template
struct function_traits {
enum { arity = sizeof...(Args) };
typedef function f_type;
};
// for pointers to member function
template
struct function_traits {
enum { arity = sizeof...(Args) };
typedef function f_type;
};
// for function pointers
template
struct function_traits {
enum { arity = sizeof...(Args) };
typedef function f_type;
};
template
static typename function_traits::f_type make_function(L l){
return (typename function_traits::f_type)(l);
}
//handles bind & multiple function call operator()'s
template
auto make_function(T&& t)
-> std::function()...)))(Args...)>
{return {std::forward(t)};}
//handles explicit overloads
template
auto make_function(ReturnType(*p)(Args...))
-> std::function {
return {p};
}
//handles explicit overloads
template
auto make_function(ReturnType(ClassType::*p)(Args...))
-> std::function {
return {p};
}
// testing
using namespace std::placeholders;
int foo(int x, int y, int z) { return x + y + z;}
int foo1(int x, int y, int z) { return x + y + z;}
float foo1(int x, int y, float z) { return x + y + z;}
int main () {
//unambuiguous
auto f0 = make_function(foo);
auto f1 = make_function([](int x, int y, int z) { return x + y + z;});
cout << make_function([](int x, int y, int z) { return x + y + z;})(1,2,3) << endl;
int first = 4;
auto lambda_state = [=](int y, int z) { return first + y + z;}; //lambda with states
cout << make_function(lambda_state)(1,2) << endl;
//ambuiguous cases
auto f2 = make_function(std::bind(foo,_1,_2,_3)); //bind results has multiple operator() overloads
cout << f2(1,2,3) << endl;
auto f3 = make_function(foo1); //overload1
auto f4 = make_function(foo1); //overload2
return 0;
}