Using Boost Thread and a Non-Static Class Function

Using boost thread and a non-static class function

The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.

If you were to call bind from outside a class member function, you might say something like:

int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}

Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:

void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}

If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:

boost::thread* thr = new boost::thread(some_regular_function);

boost::thread invalid use of a non-static member function

You should send object also.

boost::thread thread_foo(&Class::foo, this);

or

boost::thread thread_foo(boost::bind(&Class::foo, this));

Is it possible to launch boost thread on a non static member function from other memeber function

Yes...

void infiniteRun()
{
boost::thread thr(boost::bind(&sayHello::repeatHello,this));
}

Although doing it that way fraught with danger of memory leaks and access violations. When dealing with threads, I would highly recommend using smart pointers to keep things alive correctly.

boost::thread within a class

You should initialize thread_ as:

Test()
: thread_( <initialization here, see below> )
{
}

Process is a member non-static method of class Test. You can either:

  • declare Process as static.
  • bind a Test instance to call Process on.

If you declare Process as static, the initializer should just be

&Test::Process

Otherwise, you can bind an instance of Test using Boost.Bind:

boost::bind(&Test::Process, this)

invalid use of non-static member function when using boost bind - c++

You have two problems:

The first is that non-static member function needs an object to be called on. This is usually passed as a hidden first argument. You solve this by passing this as the first argument to the member-function you want to call.

The second problem is that you need to use explicit pointers to member functions. This is done by fully scoping it and using the address-of operator &.

So the working bind call should look something like:

boost::bind(&TimerBoost::print, this, &tim, &tSec)

Another possible solution, that is usually preferred over "binding", is to use lambdas:

tim.async_wait([tim, tSec, this]()
{
print(&tim, &tSec);
});

std::thread constructor argument error Invalid use of non-static member function

new thread(this->thr_process, client)

That's not how to address a member function, plus you need to bind the this pointer so the thread knows what object to call it on.

Fortunately, thread's constructor makes this easy (recall that there is a hidden "this" first argument to member functions, which this feature simulates):

new thread(&thr_process, this, client)

Read the chapter in your book about threads for more information.

Also consider reducing your excessive use of dynamic allocation.

Creating a boost::thread with boost::bind() or without

As you can see by the code below that compile and gives the expected output, boost::bind is completely unnecessary for using boost::thread with free functions, member functions and static member functions:

#include <boost/thread/thread.hpp>
#include <iostream>

void FreeFunction()
{
std::cout << "hello from free function" << std::endl;
}

struct SomeClass
{
void MemberFunction()
{
std::cout << "hello from member function" << std::endl;
}

static void StaticFunction()
{
std::cout << "hello from static member function" << std::endl;
}
};

int main()
{
SomeClass someClass;

// this free function will be used internally as is
boost::thread t1(&FreeFunction);
t1.join();

// this static member function will be used internally as is
boost::thread t2(&SomeClass::StaticFunction);
t2.join();

// boost::bind will be called on this member function internally
boost::thread t3(&SomeClass::MemberFunction, someClass);
t3.join();
}

Output:

hello from free function
hello from static member function
hello from member function

The internal bind in the constructor does all the work for you.

Just added a few extra comments on what happens with each function type. (Hopefully I've read the source correctly!) As far as I can see, using boost::bind externally will not cause it to also double up and be called internally as it will pass through as is.



Related Topics



Leave a reply



Submit