I know questions like this have been asked, but none of the answers have helped me. Although I have coded some C++ in the past as needed I am not fluent by any stretch. Today, I am stuck trying to pass a callback function to a function in another class. Below is a short example:
#include "stdafx.h"
#include <functional>
class A
{
private:
int _someMemberVar = 7;
public:
void SomeFunction(std::function<void(int)> func)
{
func(_someMemberVar);
}
};
class B
{
public:
void DoSomeWork()
{
A a;
// error C2275: 'std::function<void (int)>' : illegal use of this type as an expression
a.SomeFunction(std::function<void(int)> &B::MyCallback);
}
void MyCallback(int i)
{
printf("parameter is %d\r\n", i);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.DoSomeWork();
return 0;
}
I have tried the example code from this std::function documentation page, but it doesn't compile. I had similar issues with other examples I found, such as those in the dissertation here. I am using Visual Studio 2013.
Googling the various compiler errors hasn't helped me sort this out and I'm feeling frustrated and confused. About the only thing I know for sure is that we C# programmers sure are spoiled. Any help is greatly appreciated.
Edit: Thanks so much for all the help everyone. All the answers provided a working solution, and if I could green check them all I would. I went with the answer posted by super because it had the most explanation and seems closest to what I am porting. Thanks again all!
Apart from the missing brackets around &B::MyCallback (typo?) the main issue here is that a member function and a normal function are not the same thing.
A member function acts on an object, while a function does not, so a pointer to a member function can't just be converted to a normal function pointer.
The most straight forward solution in your case is to pass a lambda that captures this.
a.SomeFunction([&](int i){ MyCallback(i); });
The lambda will capture the current object and forward i as a parameter to the member function.
Logically, you need an object to call the callback function on. Here's one way to do it:
a.SomeFunction([this] (int const i) { MyCallback(i); });
Here's another way to do the same thing. Assuming that you don't want to change the method into a static method and you want to call the MyCallback method on this
using namespace std::placeholders;
std::function<void(int)> func = std::bind(&B::MyCallback, this, _1);
a.SomeFunction(func);
Related
Using repl, it appears to be completely legal, however is there any undefined behavior/compiler-specific issues at play here?
https://repl.it/repls/ContentPutridMacro
googling for the 'this' usage inside of a header doesn't seem to turn up anything useful. Here is a copy of my example if the repl link doesn't work.
Multiplier.h :
#include <functional>
class Multiplier
{
public:
Multiplier(int i);
void multiplyBy(int j);
std::function<void()> multiplyBy100 = std::bind(&Multiplier::multiplyBy, this, 100);
private:
int priv;
};
Multiplier.cpp:
#include <stdio.h>
#include "Multiplier.h"
Multiplier::Multiplier(int i) : priv(i)
{
// empty
}
void Multiplier::multiplyBy(int j)
{
printf("value = %d\n", priv * j);
}
How I'm understanding this currently is that when you create an instance of Multiplier, say
Multiplier m(25);
It will create a Multiplier object and put all its member variables on to the stack, one of them being
std::function<void()> multiplyBy100
meaning that instance can know what value 'this' should be pointing to. Maybe I'm overthinking this but I just have never seen something comparable before.
Thank you for the help!
You can use this inside a non-static data member initializer. The C++17 standard explicitly mentions this in paragraph [expr.prim.this]/3.
Whether this appears inside a header is irrelevant. A header is just a piece of code that gets "pasted" into another file when included.
So I have a group project that is comparing the sort times of various sorting functions. I am trying to cut down the amount of copy/pasting code by using a variadic template function. I have read everything I can find on google about them and how to pass functions as parameters. It has been literally DAYS of working on this, and I can't seem to make this work. I've been able to pass a function that is defined in my main cpp file outside of a class, but I can't make it work for the functions that belong to a class.
My group has asked me to abandon this idea (we are running out of time), but I feel like I am so close to getting it. If anyone can help out with the syntax, I would be so grateful. I also tried using the function type from the functional library, which was the only way that semi-worked. I did find this question on stack overflow and the guy had the same error I was getting about using '&', but I still can't seem to make this work.
edit
As per the comments, I tried to make the code as basic and concise as possible. :)
I spent more time than I should have trying to find the function that I had gotten to work, but I did not save a copy of it. I read that I should include code that allows others to duplicate the error, but I have not been able to re-create it. The best I can do is a hypothetical example at this point.
Lets say I have a function in a class called Sorts:
void Sorts::InsertionSort(vector<int> &v_small, int length)
{
//does the thing that sorts the stuff
cout << "display the sorted stuff" << endl
}
and a vector in a class called Data:
class Data{
public
vector<int> dataSmall;
};
both of these are in a separate header file. For simplicity, lets call it "header." :)
run_timer(InsertionSort, vector_to_sort, size_of_vector);
I also have a function, in my cpp file, that (is attempting) to take a function parameter, a vector parameter, and a size parameter.
template <class Ret, class... Args> class function<Ret(Args...)>
run_timer3(function<void(Args...)> sort_func(int), vector<int>& array, int size...)
{
//start the timer
//call function to time, sort_func sometimes has 3 parameters though
sort_func(array, size);
//stop the timer
//calculate and write to file
}
I know I should be able to figure this out with generic examples but I'll just be honest it does not compute. All I need is to know how to pass a function that exists in a class. Although now that I lost the function that was working, maybe I need some help making the function definition as well. :(
This was probably the most helpful page I had found on variadic templates.
Sorry if this is to similar to the one I linked before, but I really can't understand what it is I'm doing wrong. I really don't want to have to have the same block of code with different variables 162 times. If anyone can offer guidance I will send you cyber feet-kisses. Thanks!
Since your question contains way more code then I feel like sifting through, I'll just give you an example on how to pass a function to a template.
#include <iostream>
template <typename F>
void foo(F f) {
f();
}
struct bar {
void print() {
std::cout << "bar\n";
}
void baz() {
foo([&]() { print(); });
}
};
void print() {
std::cout << "free\n";
}
int main () {
foo(print);
bar b;
b.baz();
foo([&]() { b.print(); });
}
A free function can simply be passed in. If you want to pass a member-function you can wrap it in a lambda.
I am in a position to choose between function pointers and subclassed objects. To make it clear, say I have to notify some object of some action (a timer for example); refer to the following two choices (a very basic code for demo purposes):
Version 1
typedef void TimerCallback(void *args);
class Timer{
public:
Timer();
~Timer();
void schedule(TimerCallback *callback, void *args, long timeout)=0;
void cancel();
};
Version 2
class TimerTask{
public:
TimerTask();
virtual ~TimerTask();
void timedout()=0;
};
class Timer{
public:
Timer();
virtual ~Timer();
void schedule(TimerTask *callback, long timeout)=0;
void cancel();
};
which one is the standard C++ way and which one is efficient? Please let me know if you have any other suggestions in this regard.
Please let me know if I am not clear in this regard.
Thanks
I would say std::function and std::bind. Then it doesn't matter if you want to use inherited classes, standalone functions, member functions or lambdas.
By the way, if anyone is curious I made a simple timer event handling some time ago, as an answer to another question. It's showcasing the use of e.g. std::function and std::bind: https://stackoverflow.com/a/11866539/440558.
I think it's better to use boost(or std since C++11)::function to hold callback and boost::bind to bind it's arguments, or to use boost::signal.
That would be more general and verbose solution at cost of really small penalty.
http://www.boost.org/doc/libs/1_53_0/doc/html/signals2.html
You are using object-oriented programming and you should follow the object-oriented programming paradigms.
In my opinion using objects, not function pointers, is the cleaner and generally better way to do.
You can also attempt to use a visitor pattern to make the code even better and more flexible.
You can also consider publisher/subscriber pattern.
Function pointer effectively prevents you to use closures - assigning methods to you event handler (This is not entirely true, but it will restrict you in such way, that this solution is not much of a use).
I would vote on object-oriented approach. If you use C++11, you may simplify your code a lot:
#include <cstdio>
#include <functional>
class Emitter
{
private:
std::function<void(int)> eventHandler;
public:
void SetEventHandler(std::function<void(int)> newEventHandler)
{
eventHandler = newEventHandler;
}
void EmitEvent()
{
eventHandler(42); // + error-checking
}
};
class Handler
{
private:
void HandleEvent(int i)
{
printf("Event handled with i == %d\n", i);
}
public:
void AttachEmitter(Emitter & e)
{
e.SetEventHandler([this](int i) { HandleEvent(i); });
}
};
int main(int argc, char * argv[])
{
Emitter e;
Handler h;
h.AttachEmitter(e);
e.EmitEvent();
}
Both work. Your first one is "C style" and will require a static function somewhere. The second version is "C++ style" and allows you to use an instance of TimerTask.
Generally, version 2 should be used because it removes the need for a static function.
Using code from http://ideone.com/5MHVz
I am curious how is it possible that I can bind a lambda function (inline) to a C style function pointer but I cannot do this with a class function even if there is no state involved. It must be some fundamental difference but I don't understand how lambda binding is possible in this case then (there is a conceptual this to lambda generated code also). Is there a workaround ?
Code bellow:
#include <iostream>
#include <functional>
using namespace std;
typedef int (*http_cb) (int*);
struct http_parser_settings {
http_cb on_message_begin;
};
class HttpParser
{
int OnMessageBegin(int* val){}
HttpParser()
{
http_parser_settings settings;
//settings.on_message_begin = std::bind(&HttpParser::OnMessageBegin, this, std::placeholders::_1); -- this one does not compile
settings.on_message_begin = [](int* p){ return 0;};
}
};
int main() {
}
Non-capturing lambdas can be converted to function pointers. They're essentially free functions, so there's no problem.
You can store lambdas in std::function objects even in MSVC2010, so there must be a way to get a raw function pointer. I've never delved into the details of how it works, but have certainly used this feature before.
I have a C++ class 'Expression' with a method I'd like to use in my Objective-C class 'GraphVC'.
class Expression {
double evaluate(double);
}
And my Objective-C class:
#implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
#end
I thought that it would be easiest to pass around function pointers that take a double and return a double, as opposed to C++ objects, but I haven't had much success using functional.h. What's the best way to use my C++ method from Objective-C?
EDIT: Thanks for your quick responses. Allow me to elaborate a bit... I have a backend written in C++ where I manipulate objects of type Expression. There's subclasses for rational, polynomial, monomial, etc. My initial idea was to use mem_fun from , but I wasn't able to get code compiling this way. I also had trouble using bind1st to bind the this pointer.
Writing an Objective-C wrapper is a possibility, but I'd rather use the already existing evaluate() function, and I don't want to break the clean separation between the backend and the iPhone GUI classes.
I can't have a global expression or use a static method (I need to plot arbitrary Expression instances.
I should have more explicitly stated that I need to pass a C++ member function (not a static function or existing C function) to an Objective-C object. Has anyone had luck using C++'s <functional> to turn member functions into pointers I can use in an Objective-C object, or should I use an Objective-C wrapper?
If you want to make a pointer to a method in C++, you need to include the class name, like this:
class Foo
{
public:
double bar(double d)
{
return d;
}
};
void call_using_obj_and_method(Foo *f, double (Foo::*m)(double d))
{
(f->*m)(3.0);
}
int main()
{
Foo f;
call_using_obj_and_method(&f, &Foo::bar);
return 0;
}
Note that you need an instance of the class as well. In my example this is another parameter, though you could let it be a global variable, or a singleton instance of class Foo.
Though, like jkp said, you can also solve the problem by making the method static or turning it into a regular function.
EDIT: I'm not sure if I understand your question correctly. I don't think you need to use functional. Here is how my example would look in Objective-C++:
#include <Cocoa/Cocoa.h>
class Foo
{
public:
double bar(double d)
{
return d;
}
};
typedef double (Foo::*fooMethodPtr)(double d);
#interface Baz : NSObject
{
}
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m;
#end
#implementation Baz
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m
{
(f->*m)(3.0);
}
#end
int main()
{
Foo f;
Baz *b = [[Baz alloc] init];
[b callFooObj:&f method:&Foo::bar];
return 0;
}
I would suggest wrapping the C++ class in an Objective-C class, and then also providing a
- (void) plotWithObject:(id)obj
{
double result = [obj evaluate: 1.5];
// ... etc ...
}
in addition to the plot: method.
I think the problem here is that you are trying to pass a member function of your Expression class to the Objective-C class. This will not work because it's expecting a this pointer as the first argument to that function (therefore the signature is not the same as the one expected by the plot: method.
If you make the C++ method a static, you can do this, but then you don't buy yourself a lot over using a standard C function.
IE, if the Expression class looked like this:
class Expression {
static double evaluate(double);
}
You should be able to call it like this:
[self plot:myExpression.evaluate(&Express::evalulate)];
As I say though, there isn't a huge amount of value in this because you may as well be using a standard C function (unless you can do something in the C++ class that is more useful to you).
I did once look at trying to bridge boost::bind() results with objective-c methods but didn't get very far. I'm sure if you dig deep enough in the C++ runtime you could do it though.
If your C++ member function returns a double, can't your code just look like this?
- (void)plot:(double)f;
...
[self plot:myExpression.evaluate(aDouble)];
Or something similar. I've not used much mixing of Obj-C and C++, but this is how I would approach it. You also might have to have a .mm extension on your Objective-C++ file if you're mixing them like that.
Why wouldn't you pass the instantiated c++ class around inside an NSValue and then call the c++ method directly?
- (NSValue*)getExpression
{
Expression* e = new Expression();
return [[NSValue alloc] initWithPointer:e];
}
- (void)callExpression(NSValue*)expression
{
Expression* e = [expression pointerValue];
e->evaluate();
}