boost::bind function with its input argument error - c++

I am trying to do multithreading by boost::bind. But, I got error:
src/model.cpp:225: instantiated from here
/boost_1_45_0v/include/boost/bind/mem_fn.hpp:333: error: pointer to member type void (Model::)(taskDataSPType&) incompatible with object type taskDataSPT1ype
make: * [model.o] Error 1
Here is my code:
void Model::runTask(taskDataSPType& myTask)
{}
taskDataSPType myTask;
fifo_pool tp(thread_num);
for (int i = 0 ; i < totalTaskNum ; +i)
{
taskQueue.wait_and_pop(myTask, i);
myTask.taskID = i ;
// run the typical iterations
tp.schedule(boost::bind(&Model::runTask, &myTask));
}
tp.wait();
In another header file, I have :
typedef struct taskDataSPT1ype taskDataSPType;
struct taskDataSPT1ype
{
int taskID;
int startNode;
int endNode;
};

Model::runTask is (presumably) a non-static member function. That means you cannot call it without an instance of the class. boost::bind knows this, and therefore it expects the first parameter to be a Model of some form, or a derived class thereof. So your bind takes two parameters: the Model and the function argument taskDataSPType&.
Also, your argument is a reference, but you seem to be attaching a pointer. That's not going to work either. You may need to use boost::ref, as follows:
tp.schedule(boost::bind(&Model::runTask, /*Some Model Instance*/,
boost::ref(myTask)));

&Model::runTask is a member function, and as such it has an extra implicit argument this. So in your particular case, you want to bind it with two arguments: an instance of Model and a taskDataSPType object. Note that if one wants to pass references with bind it has to use boost::ref or boost::cref.

Related

Lambdas and passing a pointer class as argument

I'm having problems with passing a class pointer as a parameter in a lambdas callback.
pastebin: http://pastebin.com/SqXHtGDt
How I define the callback:
typedef void (*cb_prescription)(Prescription * prescription);
How I use the callback:
void loop_prescriptions (cb_prescription callback, bool add = true)
{
for (int i = 1; i <= prescriptions->noOfElements(); i++) {
Prescription * prescription = (Prescription *) prescriptions->removeNo(i);
if (add) {
prescriptions->add(prescription);
}
callback(prescription);
}
}
I know that everything works, except the parameter pointer part.
loop_prescriptions ([&] (Prescription * paper) { paper->something(); });
The error I'm getting:
error: cannot convert ‘list_prescriptions_by_doctor()::’ to ‘cb_prescription {aka void ()(Prescription*)}’ for argument ‘1’ to ‘void loop_prescriptions(cb_prescription, bool)’
});*
Does anyone know how I'm using the parameter incorrectly?
I've tried to add a reference for the pointer as *&, and just removing the pointer, but the List class (yes I must use this) returns a class pointer, so I cannot simply use a copy.
Thanks for any help!
UPDATE
I've updated my pastebin based on the answer, which gives a working solution.
http://pastebin.com/7yTPGEQx
Your function only accepts function pointers, while you are passing a lambda (or in other words, any random class). Since classes aren't function pointers, most likely would like to accept functors (e.g. Everything which is function like)
I guess you can change your code in 2 different ways:
// Using a std::function object; which wraps both function pointers and classes with () operator
using cb_prescription = std::function<void(Prescription*)>;
or
template<typename cb_prescription>
void loop_prescriptions (cb_prescription &&callback, bool add = true)
The first variant is the one that I would prefer, as this is very generic, unfortunately it comes with a performance overhead from wrapping the callback. Unless you are in performance critical code, I would use this one.
The second variant works via templates, so whatever you pass there that can be called with () operator and matching arguments will work. However it requires this code to be available for all callers. Due to the the template, the exact type of the function-ptr, lambda is known, so you will not get the overhead from the std::function.

In C++, how can you pass an object's method as a parameter to a function?

So, I have a function, called Romberg, that takes a function as first parameter:
int Romberg(double (*f)(double), ... );
When executed, it applies the passed function to several values.
In a class, I have defined the following methods:
double Funktion::q(double x){
return(sqrt(1.0+fd(x)*fd(x)));
};
void Funktion::compute_bogen(){
Romberg(q, ... );
};
Where fd is another method from the same class. This however, doesn't work! I tried altering the code in the following way, which ends up with successfully passing the method to the Romberg function; but then it fails to apply the passed function:
int Romberg(double (Funktion::* &f)(double), ... );
void Funktion::compute_bogen(){
Romberg(&Funktion::q, ... );
};
I get the following error message:
error C2064: term does not evaluate to a function taking 1 arguments
Right now, I do not see how to make this work without throwing away the whole class system I built.
I get the following error message:
error C2064: term does not evaluate to a function taking 1 arguments
This is because Funktion::q secretly takes 2 arguments, a this pointer and the double
The problem is that Romberg doesn't have any information about the object that calls it in Funktion::compute_bogen(), so it can't give it to Funktion::q(). You probably want something like this:
typedef double (Funktion::*RombergFuncArg)(double)
int
Romberg(RombergFuncArg func, Funktion& obj, ... )
{
double input = 0.0;
double output = (obj.*func)(input);
//...
}
[Edit] In reply to the comment:
void Funktion::compute_bogen(){
Romberg(&Funktion::q, *this, ... );
};
To make it work with your class system, you need to define fd to take a pointer to a member function instead of a pointer to a function (the two are not the same).
Then you'll need to invoke it correctly for a pointer to a member function as well (which is slightly different than invoking a pointer to a function).
I'd note that although you can do this, you might be better off considering a somewhat different structure. One that's fairly common is to use a virtual function, which you'll override in various derived classes. Then instead of using a pointer to a member function, you select the object that implements the function you want, and invoke the virtual function in that object.

compilation error C++ : can not call member function without object

I have the following main file where I tried to create a map with predefined value and pass it for further processing by other method. The main file is as is shown below :
int main(){
map<id,Porto> _portoInit;
id = 1;
Porto p;
p.val = 5;
_portoInit.insert(pair<id, Porto>(id, p));
Porto::setPorto(_portoInit);
return 1;
}
where the setPorto is defined under a class as the following (in seperate file)
void Porto::setPorto( const map<id,Porto>& _portoblock ) {
//do stuffs
};
I got prompted with an error of "error: cannot call member function ... without object"
Did not I declare the object of _portoInit in the main file already or it is a wrong way of declaration?
You need to invoke the method through the actual object:
p.setPorto(_portoInit);
Unless setPorto is a static method, your code is invalid.
You should write
p.setPorto(_portoInit);
The "::" defines the scope of the function and is implicit in the above, as the object who's function is being called is a Porto.
setPorto is a non-static member function, so you need to call it on a Porto instance. For example:
p.setPorto(_portoInit);
Note that non-static member functions take an implicit first parameter of (possibly cv qualified) type T*, so you could have called it like this:
Porto::setPorto(&p, _portoInit);
In both cases, you need an object to call the member function on. This is what the compiler is telling you.

Pointer to function won't compile

//mediafactory.h
class MediaFactory{
public:
typedef Media* (*funPointer)();
funPointer somePointer;
}
//mediafactory.cpp
Media* MediaFactory::returnMedia(){
}
when I try to do
somePointer = returnMedia;
I get this error:
1 IntelliSense: a value of type "Media *(MediaFactory::*)()" cannot be assigned to an entity of type "MediaFactory::funPointer" c:\Users\...\mediafactory.cpp 37
However, if i change the function to the code below, it will compile and work
Media* returnMedia(){ //without scope
}
MediaFactory::returnMedia() is a non-static member function, and can only be called via an instance of MediaFactory.
typedef Media* (*funPointer)(); defines a pointer to a static or non-member function, which is called without any object. It's therefore a different type, incompatible with a pointer to a member function.
If you don't need it to point to a member function, then make returnMedia() either static or a non-member (as you note in at the end of the question).
If you do need it to point to a member function, then you need a pointer-to-member:
typedef Media* (MediaFactory::*funPointer)();
which can be set to point to a member function:
somePointer = &MediaFactory::returnMedia;
and can be called on a factory object:
Media * media = (someFactory.*somePointer)();
Alternatively, you might want to bind the function pointer to an object when you set the pointer, rather than when you use it. In this case, you could use std::function (or boost::function if you're stuck with an outdated compiler) to store an arbitrary callable object:
typedef std::function<Media*()> function;
function someFunction;
someFunction = std::bind(&MediaFactory::returnMedia, &someFactory);
Media * media = someFunction();
You cannot assign a method of a class to a global function pointer without an instance of this class.

Function Pointer - Compile time error

I am new to function pointers and I would like your help.
I am having a method:
int test3(int i)
{
return i;
}
Then in another method(not main) I do:
int (*pTest3)(int) = test3;
From the examples that I have read this seems ok.
However, I get a compile time error:
testFile.cpp:277:25: error: argument of type ‘int
({anonymous}::CheckingConsumer::)(int)’ does not match ‘int (*)(int)’
I do not understand what is wrong. Any help would be appreciated.
Thanks a lot.
Your test3 is a member function of a struct or a class. Class member functions have a hidden this parameter passed into them and so cannot be used with plain function pointers. You need to either declare the function as static or move it outside the struct/class, so that it no longer has a hidden this parameter, or use a class method pointer instead of a function pointer:
// static class method:
class X
{
static int test3(int i)
{
...
}
};
// Non-class method, at global scope
int test3(int i)
{
...
}
// Class method pointer
class X
{
int test3(int i)
{
...
}
};
// Create the method pointer
int (X::*pTest3) = &X::test3;
X *obj;
// Call the method pointer on an object
(obj ->* pTest3)(42);
Your method test3 seems to be an instance method. Later on you define pTest3 as function pointer, not as member function pointer.
Main difference between simple pointers and member pointers is that using the member pointer requires an instance of the object. An instance of the object tells what object should be processed and the value of the pointer tells what data field of the object should be used or what member function should be called. Value of the member pointer is conceptually equivalent to the offset from the beginning of the object to its member.
Declaring the member pointer using typedef:
typedef int (SomeClass::*MyMethodPtr)(int i);
MyMethodPtr ptr3 = SomeClass::test3;
Now using this pointer:
class SomeClass *pab = &ab;
int ret_value = (pab->*ptr3)(4);
Note that the instance of the class is used. There is other important point about the member pointers. They are implemented as structs that contain inside from 2 to 5 simple pointers and offsets depending on the compiler and other aspects like multiple inheritance, presence of vitrual base classes, etc.