Error "member function redeclaration not allowed" with boost::thread - c++

I have this problem with boost::thread that i cannot solve.
I have a classX.h file:
#include <boost/thread/thread.hpp>
class classX{
...
void startWork(void);
void doWork(void);
...
}
and then a .cpp file:
...
void classX::startWork(){
boost::thread(&doWork);
}
void classX::doWork(){
...
}
I cannot compile, i obtein the error (at the line in which i do boost::thread(&doWork)):
error C2761: 'void plsa_mt_2::doWork(void)' : member function redeclaration not allowed
Is this error related with the thread creation or with something else? What can i do to solve it?

Since classX::doWork() is a member function of classX, you can't call the member function pointer (&classX::doWork) without providing a pointer to a classX.
The Boostiest way to accomplish this is by using Boost Bind to create a callable functor with the member function pointer and a pointer to the classX, like so:
void classX::startWork() {
boost::thread t(boost::bind(&classX::doWork, this)); // be careful, the boost::thread will be destroyed when this function returns
}
You could alternatively make doWork() a static member function or a global function if doWork() doesn't need access to instance properties of the classX:

firstly, the correct syntax for getting a pointer to a member function is
&classX::doWork
However I tink you might not be showing the exact code yielding the error, because the typical error for &doWork in VS is
error C2276: '&' : illegal operation on bound member function expression

Related

Using threads with Classes in C++

Say I have an object called myObject of class myClass. It has a function
void myFunction()
What is the syntax to call this function with a thread?
I tried
std::thread myThread(myObject.myFunction)
but I'm given a syntax error and can't seems to find the correct syntax.
The error message is:
function "std::thread::thread(const std::thread &)" cannot be referenced -- it is a deleted function
Thanks for any help.
You can write:
std::thread myThread(std::bind(&myClass::myFunction, myObject));
Being, myClass the class name of myObject. This is the syntax for a pointer-to-member-function.
Also, you can add any other argument your myFunction requires just after myObject.
according to GCC , here is the error : http://coliru.stacked-crooked.com/a/4fcba365c9b25d1e
which makes sense, because member function is bound to this pointer , member variabes and many more. I'd go with lambda expression :
std::thread t ([&]{
myObject.myFunction();
})
working example : http://coliru.stacked-crooked.com/a/0be834a7249bfac9
btw, this practice of wrapping everything with anonymous function is very common in JavaScript, and should be used also here
Possible duplicate.
std::thread myThread(&myClass.myFunction, myObject)

Unknown Syntax void (Type::m_function)()

I am currently reading through some code and came across a few lines I do not understand.
First
void Foo()
{
(((Type*)parent)->*m_function)();
}
As far as I can tell they are casting the parent to Type and then calling a dereferenced function? I am not sure I have seen the ->*m_function before.
Also I can not see where m_function is declared perhaps here? Which contains more syntax I do not understand. Is it declaring a function that returns void and takes a parameter of a function? But where is the function name?
class Foo()
{
void (Type::*m_function)();
};
It's calling a member function using a pointer to this function: C++ Call Pointer To Member Function
Yes, void (Type::*m_function)(); declares m_function member of type "member function of Type taking 0 args and returning void"

Passing a function as an argument in c++

I have the following call:
void Derived::GetEntry(Skill&);
InorderTraverse(GetEntry);
Which calls
void Base<ItemType>::InorderTraverse(void Visit(ItemType&)) const
Attempting to compile as written generates
error C3867: 'Derived::GetEntry': function call missing argument list; use '&Derived::GetEntry' to create a pointer to member
Using &Derived::GetEntry generates
cannot convert parameter 1 from 'void (__thiscall Derived::* )(Skill &)' to 'void (__cdecl *)(ItemType &)'
Changing the declaration to static void GetEntry... fixes these problems, but creates a new set of problems (namely that I can't access non-static objects (nonstatic member reference must be relative to a specific object)
I have a similar traversal operation that works fine with a static declaration, since the called function just displays information about each object on which it is called.
I've been searching for a few days now for an answer, and I feel like it's something simple. Is there a way to use a nonstatic function as a parameter in another function call?
The complete code is: https://github.com/mindaika/SkillTree
Edit: Inserted full working example instead.
I suggest you use the std function pointers instead.
For instance:
#include <functional>
void main()
{
class TheClass
{
public:
TheClass()
{
m_function = ( std::tr1::bind(&TheClass::run, this) );
};
void run()
{
// stuff to do
};
std::tr1::function<void ()> m_function;
};
TheClass theclass;
theclass.m_function();
}
m_function (); // call function
As I mentioned in my question, I was trying to get around the "memory leak" caused by using a static variable (it's not actually a leak, since statics are destroyed, but not until after the leak detector runs). I ended up using a modification of the encapsulated pointer described here: C++ freeing static variables

QtConcurrent with member function

I create a QFuture that I want to use to parallelize calls to a member function. More precisely, I have a class solveParallel with .h :
class solverParallel {
public:
solverParallelData(Manager* mgr_);
virtual ~solverParallel(void);
void runCompute(solveModel * model_);
bool resultComput();
private:
Manager *myMgr;
QFuture<bool> myFutureCompute;
};
where the methode runCompute() is creating the myFutureCompute member. .cpp looks like
solveParallel::solveParallel(Manager* mgr_)
:m_mgr(mgr_)
{
}
solverParallel::~solverParallel(void){}
void solverParallel::runCompute(solveModel* model)
{
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
}
bool solverParallelData::resultComput()
{
return m_futureComput.result();
}
Include(s) are all right. Compilation fails, on line
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
with this error:
Error 44 error C2784: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1),const Arg1 &)' : could not deduce template argument for 'T (__cdecl *) (Param1)' from 'Manager **' solverparallel.cpp 31
In addition, on mouse info for '&Manager' in same line of code stands: Error: a nonstatic member reference must be relative to a specific object.
Do you see where is the trick? Thanks and regards.
From the official documentation :
QtConcurrent::run() also accepts pointers to member functions. The
first argument must be either a const reference or a pointer to an
instance of the class. Passing by const reference is useful when
calling const member functions; passing by pointer is useful for
calling non-const member functions that modify the instance.
You are passing a pointer to a pointer. Also notice that you cannot pass the arguments the way you do, but as extra arguments in the run function. The following should work:
futureComput = QtConcurrent::run(this->myMgr,&Manager::compute, model);

how to call a thread member function from main ( )

I'm getting errors while compiling a program that uses threads. Here is the part that is causing problems.It would be nice if anybody told me if I'm calling the thread function in the right way .
In main.cpp:
int main()
{
WishList w;
boost::thread thrd(&w.show_list);
thrd.join();
}
In another_file.cpp:
class WishList{
public:
void show_list();
}
void WishList::show_list(){
.
.
.
.
}
I'm getting the following error
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say ‘&WishList::show_list’
/home/sharatds/Downloads/boost_1_46_1/boost/thread/detail/thread.hpp: In member function ‘void boost::detail::thread_data<F>::run() [with F = void (WishList::*)()]’:
/home/sharatds/Downloads/boost_1_46_1/boost/thread/detail/thread.hpp:61:17: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((boost::detail::thread_data<void (WishList::*)()>*)this)->boost::detail::thread_data<void (WishList::*)()>::f (...)’, e.g. ‘(... ->* ((boost::detail::thread_data<void (WishList::*)()>*)this)->boost::detail::thread_data<void (WishList::*)()>::f) (...)’
EDIT : Having problems installing Boost library for threads. Shall try this as soon as it works
The syntax to take the address of a member function is &ClassName::FunctionName, so it should be &WishList::show_list, but now you need an object to call the function pointer on. Best (and easiest) is to use boost::bind:
#include <boost/bind.hpp>
WishList w;
boost::thread t(boost::bind(&WishList::show_list, &w));
Nothing to do with threads, this is just "how do I obtain a pointer to a member function". Do what the compiler says, say &WishList::show_list. But you may also need to pass the instance pointer along.
Update: Yes, use bind like Xeo says.
Regarding your title: Note that the function does not "belong to the thread". Classes are not part of threads. All threads access the same memory -- each thread has its own space for automatic storage, but there's nothing in a class definition that says "this goes in a separate thread".