Accessing external context within lambdas - c++

This might be a pretty nooby question, but I wasn't able to figure it out by myself.
So, I am trying to pass a lambda into the following function:
wiringPiISR(int pin, int mode, void (*function)())
... what results in this:
wiringPiISR(Pin::BELL, INT_EDGE_RISING, [] {});
... and seems to work, so I obviously can use a lambda instead of pointing to a function.
But what I actually want to do is something like that, with capturing this to access the function onInterrupt(Pin pin) in the outer context:
wiringPiISR(Pin::BELL_1, INT_EDGE_RISING, [this] {
onInterrupt(Pin::BELL_1);
});
wiringPiISR(Pin::BELL_2, INT_EDGE_RISING, [this] {
onInterrupt(Pin::BELL_2);
});
... what results in this error message:
No matching function for call to wiringPiISR
I'm not very experienced in using c++-lambdas, I know closures from many other languages, but they obviously seem to work different in c++. This capturing seems to modify the signature of the closure, but I have no idea how to fix this, or even if there is a possible solution without pointing to an "actual" function.
Thank you in advance

C++ lambdas are only convertible to function pointers if there is no capture (and you are capturing this as stated).
Also refer to the draft C++11 standard section 5.1.2:
The closure type for a lambda-expression with no lambda-capture has a
public non-virtual non-explicit const conversion function to pointer
to function having the same parameter and return types as the closure
type’s function call operator.
As a solution, you could use std::function instead of the function pointer.

Related

C++ Auto Executing Function?

While solving Leetcode Problems I have encountered a problem solution (where generally we get access to only the solution class, not the main) where I have found this statement after class declaration & definition. I am acquainted with the inside content like cin.tie sync_with_stdio etc. But what is the auto speedup with [](){//}() is doing. Is it a self-executing function. Any help will be highly appreciated.
auto speedup=[](){
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
return nullptr;
}();
Thanks in advance.
From the [] to the } is a lambda expression, also known as an anonymous function. It was introduced in C++11. It evaluates to a pointer to a function which takes no arguments and executes the code in the given function body, then returns nullptr.
That statement is calling this lambda function and placing its return value in speedup. Since the lambda expression didn't give an explicit return type, I'm pretty sure the return type, and thus the type of the speedup variable, is nullptr_t.

C++: Creating a function object with mem_fn and bind1st

Disclaimer: This description contains a lot of Qt specific functionality. This is not necessary to answer the question, I'm just including it to explain the background.
I need to do some heavy computations in my QT application.
In order to do this, I would like to use QtConcurrent::run(myFunction) This is Qt's version of async and creates a future, which at some point will contain the result of myFunction.
The problem is that the function is both a member function and takes complex parameters.
I know that you can pass both a function and a pointer to QtConcurrent::run. The function will then be invoked on the pointer. You can even provide a list of parameters. But it seems like this list only accepts parameters such as int, double or QString.
Actual Question:
I would like to convert this line of code:
model->nextStep(simulatedResult->last().molecules, dt)
into
myFunction()
That means I need to
bind the pointer to the function
bind the arguments to the function
This is my code so far:
auto memfun=std::mem_fn(&ConcreteModel::nextStep);
auto memfun_bound_to_model=std::bind1st(memfun,model);
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules);
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt);
Unfortunately this doesn't work.
There are 18 compiler errors, here is the pastebin: http://pastebin.com/2rBQgFNL
It would be great, if you could explain how to do this properly.
Not necessary for an answer, but even better, would be code for QtConcurrent::run.
Simply use a lambda expression.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
You could also use std::bind (see #JonathanWakely's answer), but lamda expressions are imho more universal and powerful.
Also, keep in mind that reading and writing to the same memory from multiple threads will result in a data race (don't pass pointers/references to mutable data to the QT threads unless synchronization is used).
You're trying to mix the C++98 bind1st with the C++11 mem_fn, which isn't possible.
bind1st requires an adaptable binary function which means one that defines certain typedefs, and one that takes exactly two arguments. You can't use it with something that requires more than two and keep binding one argument at a time.
In C++11 it is possible to wrap function objects without those typedefs, thanks to decltype and other new features, so "adaptable binary function" is a useless concept now, and bind1st is useless and deprecated.
The solution is simply to use C++11 features instead of bind1st, e.g. std::bind or a lambda expression.
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);

Strange bracket-parentheses notation in C++, looking somewhat like a for each loop

So this is how the code looks:
auto generateHash = [](std::vector<File> &files) -> std::shared_ptr<std::string> {
// Other code here
}
What does this mean? Is it a for each loop? What do the brackets in the beginning do? What do the parentheses do? What does the arrow mean? I can't compile it because of no C++11 compiler, and I can't find it in the C++ reference.
What does this mean?
It's a lambda - a function object. You can call it like a function with a a vector of files (passed by mutable reference, for some weird reason), and it a returns string (managed by a shared pointer, for some weird reason).
std::vector<File> files = get_some_files();
std::shared_ptr<std::string> hash = generateHash(files); // call the lambda
Is it a for each loop?
No. That looks like
for (auto thing : sequence) {/* code */}
What do the brackets in the beginning do?
They signify that it's a lambda. They can contain the capture list of local variables that you want to make available to the code inside the lambda.
What does the arrow mean?
That's a trailing return type. In C++11, you can use that syntax with normal functions if you want; but it's the only way to specify a lambda's return type.
I can't find it in the C++ reference.
It's right here: http://en.cppreference.com/w/cpp/language/lambda
This is lambda function, see e.g. http://en.cppreference.com/w/cpp/language/lambda.
This is a C++11 lambda function, for a tutorial on how they work, you can look at this, else for a pure reference you can look at this.
In your case it defines an anonymous function that takes in std::vector<File> &files and returns std::shared_ptr<std::string>, and assigns this function to generateHash. the auto keyword tells the compiler to derive the type of generateHash (it this case it makes for a simple shorthand). the empty brackets ([]) means that the lambda doesn't capture and local variables for use within the lambda.

Disabling "bad function cast" warning

I'm receiving the following warning:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
This is because I need to pass as argument a member function instead of an ordinary function. But the program is running correctly.
I'd like to disable this warning (Wno-bad-function-cast doesn't work for C++) or to implement a different way to pass a member function.
No. Take this warning seriously. You should rather change your code to handle this scenario.
Pointer to member function(void (MyClass::*)(byte)) and normal function pointer (void (*)(byte)) are entirely different. See this link. You cannot cast them just like that. It results in undefined behavior or crash.
See here, how they are different:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
Now you may feel that, foo(byte) and MyClass::foo(byte) have same signature, then why their function pointers are NOT same. It's because, MyClass::foo(byte) is internally resolved somewhat as,
void foo(MyClass* const this, byte);
Now you can smell the difference between them.
Declare pointer to member function as,
void (MyClass::*ptr)(byte) = &MyClass::foo;
You have to use this ptr with the object of MyClass, such as:
MyClass obj;
obj.*ptr('a');
You can't pass a function that takes two arguments to a place that expects a function that takes one. Can't be done, forget about it, period, end of story. The caller passes one argument to your function. It doesn't know about the second argument, it doesn't pass it to your function, you can't make it do what you want however hard you try.
For the very same reason you can't pass a non-static member function where a regular function is expected. A member function needs an object to operate on. Whatever code calls your function doesn't know about the object, there's no way to pass it the object, and there's no way to make it use the right calling sequence that takes the object into account.
Interfaces that take user's functions, without taking additional data that the user might want to pass to his function, are inherently evil. Look at the qsort() function from the C standard library. That's an example of an evil interface. Suppose you want to sort an array of string according to some collation scheme defined externally. But all it accepts is a comparison function that takes two values. How do you pass that collation scheme to your comparison function? You can't, and so if you want it working, you must use an evil global variable, with all the strings attached to it.
That's why C++ has moved away from passing function pointers around, and towards function objects. Function objects can encapsulate whatever data you want.
Also, this may be helpful
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};

How can I cast or convert boost bind to C function pointer?

Suppose I have this:
void func(WCHAR* pythonStatement) {
// Do something with pythonStatement
}
And I need to convert it to void function(void) like this:
bind(func, TEXT("console.write('test')"))
Now I have struct like this:
typedef void (__cdecl * PFUNCPLUGINCMD)();
struct FuncItem {
PFUNCPLUGINCMD pFunc;
// ...
};
How can I set the pFunc of my struct to bind(func, "something")? Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
Thanks.
Ended up using the wrapping "solution" (GitHub)
I think that you can't, unless you make the resulting lamba_functor a global variable.
In that case, you could declare a function that invokes it:
void uglyWorkaround() {
globalLambdaFunctor();
}
and set pFunc to uglyWorkaround().
EDIT
Just a sidenote: if you are binding static text to the function call, you may completely omit bind() call and write just:
void wrapper() {
func(TEXT("console.write('test')"));
}
and set pFunc to wrapper().
Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
I don't think you can. However, off the top of my head, I can think of several alternatives:
Use boost::function<void()> (or std::function() if your compiler supports TR1 or C++11) instead of void (*)().
It has the ability to bind to just about anything with a somewhat compatible signature.
Put the whole code into a template, make PFUNCPLUGINCMD a template parameter, and let function template argument deduction figure out the exact type.
That's a variation on the former, actually, where you would use the result of bind() directly instead of having boost::function abstract away the gory details.
Create a wrapper that calls the functor returned by boost::bind().
A function template might help to let the compiler figure out the exact types and generate a suitable function, although I haven't tried to do that. However, since you cannot use the result of bind() as a template argument, but need to have give the function access to it nevertheless, you will need a global variable for this. (The ability to avoid this is one of the main advantages of function objects, a very versatile of which is std::function.)
Extend your PFUNCPLUGINCMD callback type to support a user-provided parameter. For C callbacks, this usually is a void*. However, if you pass the address of the object returned by bind() to your callback, you would need to convert it into a pointer to the correct type - which, AFAIK, depends on the arguments provided to bind(). In order to avoid that, you'd need to pass something that abstracts away the exact type. Again, std::function comes to the rescue.
The first idea would be the best, but it requires you to be able to change PFUNCPLUGINCMD. The last one might be best when PFUNCPLUGINCMD needs to be compatible with C, as it uses the common C callback idiom.
You can't do this, unless you want to write your own Just-In-Time compiler. Alternatively, if you control the receiving code, then you could use a boost::function<>, which will accept a variety of function types, including pointers and function objects like those produced by boost::bind.