Passing lambda with parameter - c++

I would like to pass a lambda to a funciton.
This
boost::function<void()> fncPtr(boost::bind<void>([](){/* something */}));
works, but if the lambda had a parameter, I don't know how to do it properly:
boost::function<void(bool)>
fncPtr(boost::bind<void,bool>([](bool){/* something */}, _1));
does not work.
Where I am wrong?
How to pass lambda with argument(s)?
I would like to do this in a member function.
So in "global scope"(is it the name?) this method above works fine.

This works fine for me with GCC4.5:
#include <boost/bind.hpp>
#include <boost/function.hpp>
int main() {
boost::function<void(bool)>
fncPtr(boost::bind<void>([](bool){/* something */}, _1));
}
It doesn't need the type of the parameters. Those parameter types could be templated anyway (for some functors), so in general it cannot depend on them. It only needs the return type.
Incidentally, it even works for me when I pass <void, bool>, but only when the lambdas has no captures. I think that this may work for me because GCC4.5 supports conversion of lambdas to function pointer types, when the lambdas has no capture clause. <void, bool> would make bind have a candidate that accepts a function pointer, and make the lambda convert to that. Your compiler apparently doesn't support that special conversion yet (but the FDIS requires it).
So, just pass <void> only, and it should work.

I summed up some techniques here on Ideone. Note, I used the C++0x versions, the Boost ones should work just fine too.
It really depends though on what your function wants as a parameter though. If it is simply templated or takes a (std::|boost::)function, then a simple lambda will do. No need for complicated binding or packaging in an extra (std::|boost::)function.

You have a problem in the compiler probably. I have an error in Visual Studio 2010 too. You can help compiler to convert a lambda to a function using helper function:
template <typename T>
void closureToFunction(bool x){ T f; return f(x); }
int main()
{
auto exp = [](bool x){/* something */};
boost::function<void(bool)> fncPtr(
boost::bind( closureToFunction<decltype(exp)>, _1) );
return 0;
}

Related

Is forwarding of all callables still not possible in C++20?

I would like to make a universal wrapper function which can accept any
free standing or static function,
member function ( perhaps as a specialization with the first argument used as *this)
including overloaded or templated cases together with variable arguments. Such wrapper will then, in the body, call the function exactly with the forwarded parameters.
Example:
template<typename Fnc,typename...Args>
void wrapper(Fnc fnc, Args&&...args){
// Do some stuff
// Please disregard the case when return type is void,
// that be SFINAED with std::result_of.
auto res = fnc(std::forward<Args>(args)...);
// Do some stuff
return res;
}
#include <vector>
auto foo(int i){ return i; }
auto foo(double& d){ return d; }
auto foo(double&& d){ return d; }
auto foo(const char* str){ return str; }
template<typename...T>
auto generic_foo(T&&...ts){/* ...*/ return /* ...*/; }
template<typename T>
void constrained_foo(std::vector<T>& lref,std::vector<T>&& rref, std::vector<T> value){ /**/}
int main(){
// Basics
wrapper(foo, 1);// foo(int)
wrapper(foo, 1.1); // foo(double&&)
wrapper(foo, "ahoj"); // foo(const char*)
// Conversion must work too
wrapper(foo, 1.1f); // foo(double&&)
wrapper(foo, (short)1); // foo(int)
// Detecting lvalues, rvalues is also a must
double y;
foo(y);
foo(std::move(y));
// Similarly for templates
int x;
std::vector<int> v1, v2, v3;
wrapper(generic_foo, 1, 1.1, "ahoj", x, &x);
wrapper(constrained_foo, v1, std::move(v2), v3);
}
The thing I do find so frustrating about this is that I am supplying all the necessary information to make these calls right next to each other, there is no added ambiguity about what to call, I could call it myself, I could(will) make a macro that can do it, but there is no proper C++ syntax for it AFAIK.
I discovered the need for it while trying to automatically call all my methods in certain "context". But thinking about it more, I believe this could have really widespread usage for <algorithm>, <thread> libraries too. Where you would not have to make one-statement lambdas just to call a function/operator with the lambdas parameters or something captured.
The issue arises in any function accepting another function which will be eventually called together with the passed known parameters.
My attempts
generic_foo can be resolved if the return type is fixed:
template<typename...Args>
void wrapper(void(*f)(Args&&... args) , Args&&...args){
// ...
f(std::forward<Args>(args)...);
}
int main(){
int x;
wrapper(generic_foo, 1, 1.1, "ahoj", x, &x, std::move(x));
}
This works nicely, the return type can maybe be resolved too by some obscure and clever use of std::invoke_result_t, but currently it is a kind of chicken-egg situation with the parameter type. Because the only thing how to resolve the name generic_foo is to force it to decay to a function pointer and then there is no name to put in std::invoke_result_t since the parameter is still being deduced.
This will also work with overloads as long as there is an exact match, so it cannot do conversions.
This approach is as far as I can get without macros when the function name is not known in advance.
If the name of the callable is fixed, there is this frequently-used variation of lambda trick:
template<typename Fnc, typename...Args>
void wrapper(Fnc f , Args&&...args){
// ...
f(std::forward<Args>(args)...);
}
int main(){
int x;
wrapper([](auto&&...args)
{ return generic_foo(std::forward<decltype(args)>(args)...);},
1, 1.1, "ahoj", x, &x, std::move(x));
}
If I add a macro doing exactly this:
#define WRAP_CALL(wrapper_fnc, called_fnc, ...) \
wrapper_fnc([&](auto&&...args) \
{ return called_fnc(std::forward<decltype(args)>(args)...);}, \
__VA_ARGS__ );
int main(){
int x;
WRAP_CALL(wrapper, generic_foo, 1, 1.1, "ahoj", x, &x, std::move(x))
}
I get the least macro-infested working solution I can think of, it works with any callable and any wrappers which can stay proper C++ functions. But I would like macro-less version of this and especially for functions.
So I will probably still use this version, does not seem too unreasonable. Are there any corners cases I should know about?
I did not write a single C++20 concept yet, so I still have very small hope there might be something that can work in that area perhaps? But probably not since std::thread(foo,1); also suffers from it.
So this might sadly require language changes because the name of the overload set or a template cannot currently be passed anywhere, even just as some kind of aggregated type. So perhaps something akin to std::initializer_list class plus its sometimes-magical syntax?
If this is indeed the case, I would gladly accept any answer listing any currently active proposals that might help with this. If there are even any.
I did found N3579 - A Type trait for signatures which could perhaps work together with the function pointer solution if the chicken-egg problem is addressed. But the proposal looks very dead.
The "overloaded or templated cases" are not entities that can be function/template arguments—certain cases where overload resolution can use contextual information notwithstanding. What you mean by foo in your wrapper(foo,…) is little more than a token (in particular, it's an overload set), and the language simply has no way of addressing such an object since it has no ("aggregated"?) type. (Conversely, macros do operate on tokens, which is why they are applicable here.) You seem to know most of this, but it may be helpful to see why it's knowably impossible, and why it's a bad idea to think of an overload set as "a callable". (After all, syntactically a type name is also "callable", but it wouldn't make any sense to pass one as a function argument.)
Even if a call f(g,…) were defined to try each overload of g in turn (which it is, for the narrow purpose of deducing f's template arguments), that wouldn't help for (an overload set containing) a template: there would be no way to even evaluate f's SFINAE conditions given a g template for which a specialization had not yet been chosen.
The standard lambda trick, which you also illustrated, is a way of performing overload resolution with the benefit of the argument list, which is why it's pretty much the only approach that works. There are certainly proposals to automate that process, including the vagaries of SFINAE-friendliness and exception specifications.
Consider this instead:
template <class T>
auto wrapper(T fnc) {
// Do some stuff
auto res = fnc(); // <--- no arguments
// Do more stuff
return res;
}
Since arguments are known at wrapper call time, they can also be bound at wrapper call time.
wrapper([](){ return foo(1); });
wrapper([](){ return foo(1.1); });
wrapper([](){ return foo("ahoj"); });
wrapper([&x](){ return generic_foo(1, 1.1, "ahoj", x, &x); });
You can encapsulate this in a macro, which is of course less than ideal, but at least this one is short and readable.
#define DEFER(x) ([&](){return x;})
wrapper(DEFER(foo(1)));
wrapper(DEFER(foo(1.1)));
wrapper(DEFER(foo("ahoj")));
wrapper(DEFER(generic_foo(1, 1.1, "ahoj", x, &x)));
This doesn't do exactly what you want, for example, in
wrapper(DEFER(foo(bar())))
bar is called late. This is fixable with a bit of syntax:
wrapper([z=bar()](){ return foo(z); });
and of course this can be wrapped in a macro too:
wrapper(DEFER1(foo(z), z=bar()));
although this is getting a bit unwieldy.

Pointer to member function-object in std::invoke

Why std::invoke does not work with a pointer to member which is a function object with arguments? Like this:
struct MyClass
{
std::function<void(int)> functor{ [](int arg) { printf("%d\n", arg); } };
};
int main()
{
MyClass mc;
std::invoke(&MyClass::functor, mc, 110);
}
Prints : 'std::invoke': no matching overloaded function found.
I checked this in Visual C++ and g++.
Moreover, std::is_invocable_v<decltype(&MyClass::functor), MyClass, int> claims that this functor is not invocable, which is definitely wrong.
Am I missing something or it is a defect in the standard? If this behavior is correct, then what is the point in std::invoke and all its friends? What I mean is that simple function objects can be easily called without any facilities, but I though the main purpose of std::invoke is to generalize and simplify working with all callables, including the tricky ones, like pointers to members. The fact that std::invoke cannot invoke a clearly invocable target seems weird to me.
The problem is that functor is not a function, but a data member. As such, &MyClass::functor is not a pointer to member function, but a pointer to member data. This distinction means that you cannot pass any other arguments to std::invoke, as you cannot call a data member; but for some data members, like your functor you can. The standard is not clear on this before C++11, and so there was LWG issue 1520 which got merged in C++11.
I mean you can rewrite your example as:
std::invoke(&MyClass::functor, mc)(110);
// or for maximum confusion
std::invoke(std::invoke(&MyClass::functor, mc), 110);
but I don't think that's what you want. Thanks to Barry, this is a bad idea, as what would the following code do:
struct X {
std::function<void()> f;
};
std::invoke(&X::f, x); // gets f, or calls f?
Getting f would make it consistent with other data members, but then you have no way of invoking f if f takes no arguments. Calling f means that you get an inconsistency with other data members when you just want to get them.

How I can pass callable object to function as parameter

In c++ standard library almost all algo function takes a callable object as a argument. Now I want to try this thing with my program. I opened the the headers for function like find_if or search_n() but could not understand much about how these callable object parameters are handled and off course how argument is passed to them especially for lambda object ( can bind() be used for lambdas, I dont know)
Can any one explain me how this thing works. Thanks in advance
Just have a template parameter for the function-like type and take an argument of that type:
template <typename Function>
void foo(Function func) {
// Use func like so
func(10);
}
This is how the standard library algorithms do it. You could call it with a lambda like so:
foo([](int x) { std::cout << (x * 2) << std::endl; });
Of course, this requires that you specify in your documentation what kind of function you expect as the Function type (until we get (until we get Concepts). Should it be unary? Binary? What type arguments should it take? What should it return?
Alternatively, you can take a function of a specific type by using std::function:
int foo(std::function<int(char)> func) {
return func('a');
}
This time, foo will only take function-like objects that take a char argument and return an int. There is one downside to this method, however, which is that the compiler is unlikely to inline any lambdas you pass as func.
The most basic way to take a function as an argument is with a function pointer:
int foo(int (*func)(char)) {
return func('a');
}
However, this will only take function pointers (some lambdas can be converted to function pointers). It won't take functors or anything else of the sort.
All algorithm function must get some functions to test the algo like find_if have to know which predicate you want to test on the loop. All std lib works with template and you can pass your function test as callable object. Callable object are object that have overload operator(), with it, std lib will call your sent object with some parameter and get up a return value if necessary. You can find which parameters and return values that are needed on some site, specialy I always use http://www.cplusplus.com/ you can find many documentation on all std lib in reference menu.
Special exemple from you :
http://www.cplusplus.com/reference/algorithm/find_if/
find_if will take 2 iterators, one as first and an other as last, and a callable object that will take a object pointed by your iterator and return a bool.

Why does boost::bind store arguments of the type passed in rather than of the type expected by the function?

I recently ran into a bug in my code when using boost::bind.
From the boost::bind docs:
The arguments that bind takes are copied and held internally by the returned function object.
I had assumed that the type of the copy that was being held was based on the signature of the function. However, it is actually based on the type of the value passed in.
In my case an implicit conversion was happening to convert the type used in the bind expression to the type received by the function. I was expecting this conversion to happen at the site of the bind, however it happens when the resulting function object is used.
In retrospect I should have been able to figure this out from the fact that using boost::bind gives errors when types are not compatible only at the call site, not the bind site.
My question is:
Why does boost::bind work this way?
It seems to give worse compiler error messages
It seems to be less efficient when implicit conversion happens and there are multiple calls to the functor
But given how well Boost is designed I'm guessing there is a reason. Was it behavior inherited from std::bind1st/bind2nd? Is there a subtle reason why this would be hard/impossible to implement? Something else entirely?
To test that second theory I wrote up a little code snippet that seems to work, but there may well be features of bind I haven't accounted for since it's just a fragment:
namespace b = boost;
template<class R, class B1, class A1>
b::_bi::bind_t<R, R (*) (B1), typename b::_bi::list_av_1<B1>::type>
mybind(R (*f) (B1), A1 a1)
{
typedef R (*F) (B1);
typedef typename b::_bi::list_av_1<B1>::type list_type;
return b::_bi::bind_t<R, F, list_type> (f, list_type(B1(a1)));
}
struct Convertible
{
Convertible(int a) : b(a) {}
int b;
};
int foo(Convertible bar)
{
return 2+bar.b;
}
void mainFunc()
{
int x = 3;
b::function<int()> funcObj = mybind(foo, x);
printf("val: %d\n", funcObj());
}
Because the functor may support multiple overloads, which may give different behaviours. Even if this signature could be resolved when you knew all the arguments (and I don't know if Standard C++ can guarantee this facility) bind does not know all the arguments, and therefore it definitely cannot be provided. Therefore, bind does not possess the necessary information.
Edit: Just to clarify, consider
struct x {
void operator()(int, std::vector<float>);
void operator()(float, std::string);
};
int main() {
auto b = std::bind(x(), 1); // convert or not?
}
Even if you were to reflect on the struct and gain the knowledge of it's overloads, it's still undecidable as to whether you need to convert the 1 to a float or not.
There are different cases where you need the arguments to be processed at the call site.
The first such example is calling a member function, where you can either have the member called on a copy of the object (boost::bind( &std::vector<int>::push_back, myvector)) which most probably you don't want, or else you need to pass a pointer and the binder will dereference the pointer as needed (boost::bind( &std::vector<int>::push_back, &myvector )) --Note both options can make sense in different programs
Another important use case is passing an argument by reference to a function. bind will copy performing the equivalent to a pass-by-value call. The library offers the option of wrapping arguments through the helper functions ref and cref, both of which store a pointer to the actual object to be passed, and at the place of call they dereference the pointer (through an implicit conversion). If the conversion to the target type was performed at bind time, then this would be impossible to implement.
I think this is due to the fact that bind has to work with any callable entity, be it a function pointer, std::function<>, or your own functor struct with operator(). This makes bind generic on any type that can be called using (). I.e. Bind's implicit requirement on your functor is just that it can be used with ()
If bind was to store the function argument types, it would have to somehow infer them for any callable entity passed in as a type parameter. This would obviously not be as generic, since deducing parameter types of an operator() of a passed-in struct type is impossible without relying on the user to specify some kind of typedef (as an example). As a result the requirement on the functor (or concept) is no longer concrete/simple.
I am not entirely sure this is the reason, but it's one of the things that would be a problem.
EDIT: Another point as DeadMG mentions in another answer, overloads would create ambiguities even for standard function pointers, since the compiler would not be able to resolve the functor type. By storing the types you provide to bind and using (), this problem is also avoided.
A good example would binding "std::future"s to some ordinary function taking ordinary types:
Say I want to use an ordinary f(x,y) function in an incredibly asynchronous way. Namely, I want to call it like "f(X.get(), Y.get())". There's a good reason for this- I can just call that line and f's logic will run as soon as both inputs are available (I don't need separate lines of code for the join). To do this I need the following:
1) I need to support implicit conversions "std::future<T> -> T". This means std::future or my custom equivalent needs a cast operator:
operator T() { return get(); }
2) Next, I need to bind my generic function to hide all its parameters
// Hide the parameters
template<typename OUTPUT, typename... INPUTS>
std::function<OUTPUT()> BindVariadic(std::function<OUTPUT(INPUTS...)> f,
INPUTS&&... in)
{
std::function<OUTPUT()> stub = std::bind( f, std::forward<INPUTS>(in)...);
return stub;
}
With a std::bind that does the "std::function<T> -> T" conversion at call time, I only wait for all the input parameters to become available when I ACTUALLY CALL "stub()". If it did the conversion via operator T() at the bind, the logic would silently force the wait when I actually constructed "stub" instead of when I use it. That might be fatal if "stub()" cannot always run safely in the same thread I built it.
There are other use cases that also forced that design choice. This elaborate one for async processing is simply the one I'm personally familiar with.

Lambda and bind not working together in VS2010

This code fails to compile under VS2010:
#include <functional>
using namespace std;
void test()
{
auto f = [] (int) {};
bind(f, 10);
}
It gives a long error pointing to the internals of bind implementation.
If I switch to a normal function instead of a lambda, the bind works fine, so I believe this is a bug in VS2010 but maybe I'm missing something.
Can you help me?
It seems VC10 cannot cope with lambdas as arguments to std::bind. It seems to expect either a function pointer or a function object. I don't know whether this is a bug, but I suspect it is, since lambda function should become function objects during compilation.
Anyway, if you are in need of a workaround, this compiles for me:
std::function<void(int)> func = [] (int) {};
std::bind(func, 10);