I am trying to write a wrapper make_function, which like std::make_pair can create a std::function object out of suitable callable obj
The big reason why you want to be able to convert lambdas to std::function is because you want two overloads, each taking different signatures.
A good way to solve this involves std::result_of.
Suppose you are making a loop control structure that takes a lambda or other functional. If that functional returns void, you want to loop uncontrolled. If it returns bool or the like, you want to loop while it returns true. If it returns enum ControlFlow, you want to pay attention to the ControlFlow return value (continue or break, say). The function in question takes either the element iterating over, and optionally some extra data (the index in the iteration, maybe some "location" meta-information about the element, etc).
std::result_of would let you pretend to invoke the passed in type with a different number of arguments. A traits class could then figure out which of the above signatures is the "best match", and then route to the implementation that handles that signature (possibly by wrapping the "simpler" cases in a lambda and calling the more complex cases).
Naively, your make_function would could this problem, because you could then simply overload on the various std::function< blah(etc) > cases. But with auto parameters coming down the pipe, and std::bind already doing perfect forwarding, this only handles the easiest cases.
std::result_of traits classes (and possibly related concept matching and requires clauses) and tag dispatching (or SFINAE as a last resort).
The big downside is that you end up having to manage the override order yourself semi-manually. I could see some utility in helper classes where you provide a list of signatures to match, and it either produces a boost::variant or you also produce a canonical output and a conversion method to that canonical output.
The short answer? std::bind's implementation is implementation specific details, but it may involve the equivalent of perfect forwarding of variadic parameter packs, and as such is not suitable for your "get the address of the one and only concrete operator()" technique you are using.
As another example:
template
vector map(std::function f, vector arr) {
vector res;
for (int i=0;i
should be written as:
template
using result = typename std::result_of::type;
template
using decayed_result = typename std::decay>::type;
template
vector> map(function&& f, vector const& arr) {
vector> res;
res.reserve( arr.size() );
for (A const& a : arr) {
res.push_back( f(a) );
}
return res;
}
again, result_of is the right solution, not converting things needlessly to std::function.
For fold_right we get:
template
using EnableIf = typename std::enable_if::type;
template
EnableIf<
std::is_convertible< result, dest >::value,
std::vector
>
fold_right( function&& f, std::vector const& v, dest initial )
which again skips any type erasure on f. And if you really want to do type erasure on f, you can do:
template struct identity { typedef T type; };
template using do_not_deduce = typename identity::type;
template
std::vector fold_right( do_not_deduce< std::function > f, std::vector const& v, dest init );
std::function is a type erasure object. You type erase because you want to use a type somewhere you do not want to carry the type over to. Deducing from a type what kind of resulting type erasure object you should create is almost always the wrong answer, because you have all of the dependency of non-type erased cases, and all of the inefficiency of the type erasure.
make_function's result is dependent the full type of the source, which makes type erasure output almost completely useless.