11

I am new to Boost.Threads and am trying to understand how to pass function arguments to the boost::thread_groups::create_thread() function. After reading some tutorials and the boost documentations, I understand that it is possible to simply pass the arguments to this function but I can't get this method to work.

The other method I read about is to use functors to bind the parameters to my function but that would create copies of the arguments and I strictly require that const references be passed since the arguments will be big matrices(this I plan to do by using boost::cref(Matrix) once I get this simple example to work).

Now, let's get down to the code:

void printPower(float b, float e)
{
    cout<<b<<"\t"<<e<<"\t"<<pow(b,e)<<endl;
    boost::this_thread::yield();
    return;
}

void thr_main()
{
    boost::progress_timer timer;
    boost::thread_group threads;
    for (float e=0.; e<20.; e++)
    {
        float b=2.;
        threads.create_thread(&printPower,b,e);
    }
    threads.join_all();
    cout << "Threads Done" << endl;
}

This doesn't compile with the following error:

mt.cc: In function âvoid thr_main()â:
mt.cc:46: error: no matching function for call to âboost::thread_group::create_thread(void (*)(float, float), float&, float&)â
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp: In member function âvoid boost::detail::thread_data<F>::run() [with F = void (*)(float, float)]â:
mt.cc:55:   instantiated from here
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp:61: error: too few arguments to function

What am I doing wrong?

awesoon
  • 32,469
  • 11
  • 74
  • 99
Mindstorm
  • 443
  • 1
  • 5
  • 12

2 Answers2

17

You can't pass arguments to boost::thread_group::create_thread() function, since it gets only one argument. You could use boost::bind:

threads.create_thread(boost::bind(printPower, boost::cref(b), boost::cref(e)));
#                                             ^ to avoid copying, as you wanted

Or, if you don't want to use boost::bind, you could use boost::thread_group::add_thread() like this:

threads.add_thread(new boost::thread(printPower, b, e));
awesoon
  • 32,469
  • 11
  • 74
  • 99
  • The latter approach is suitable for my problem since I cannot afford to make any copies of the arguments. However, it throws the following error: `/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp: In member function âvoid boost::detail::thread_data::run() [with F = void (*)(float, float)]â: mt.cc:55: instantiated from here /usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp:61: error: too few arguments to function` – Mindstorm May 01 '13 at 13:48
  • @Mindstorm, hmm... Code with `add_thread` works for me(boost v1.53). – awesoon May 01 '13 at 13:56
  • @Mindstorm, about avoid copying: just use `boost::cref` as you already said. I've updated answer. – awesoon May 01 '13 at 13:58
  • Great! The code compiles and runs fine with `boost::bind` and `boost::cref` – Mindstorm May 01 '13 at 14:35
6

For more flexibility you can use:

-Lambda functions (C++11): What is a lambda expression in C++11?

threads.create_thread([&b,&e]{printPower(b,e);});

-Functors that store the arguments as const references.

struct PPFunc {
    PPFunc(const float& b, const float& e) : mB(b), mE(e) {}
    void operator()() { printPower(mB,mE); }
    const float& mB;
    const float& mE;
};

-std::bind (C++11) or boost::bind

Community
  • 1
  • 1
Peter
  • 5,608
  • 1
  • 24
  • 43