Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a function using default parameter(s) to std:: thread?

So I have gcc version 4.8.1, g++ version 4.6.4, using flags: -std=c++0x and -pthread.

I simplified my problem down to the code shown and still get the original error.

What I have below compiles, but when I uncomment the two lines for thread "two", I get the error message shown below the code

#include <iostream>
#include <thread>
using namespace std;

void print_int(int x=7);
void print_A(){
    cout << "A\n";
}

int main(){
    thread one (print_int,17);
    //thread two (print_int);
    thread three (print_A);

    one.join();
    //two.join();
    three.join();

    return 0;
}

void print_int(int x){
    cout << x << '\n';
}

I tried to parse through the error messages but I still have no clue what's going on...

    In file included from /usr/include/c++/4.6/thread:39:0,
             from def_params.cpp:2:

    /usr/include/c++/4.6/functional: In member function ‘void std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__call(std::tuple<_Args ...>&&, std::_Index_tuple<_Indexes ...>, typename std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__enable_if_void<_Res>::type) [with _Res = void, _Args = {}, int ..._Indexes = {}, _Result = void, _Functor = void (*)(int), _Bound_args = {}, typename std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__enable_if_void<_Res>::type = int]’:

    /usr/include/c++/4.6/functional:1378:24:   instantiated from ‘std::_Bind_result<_Result, _Functor(_Bound_args ...)>::result_type std::_Bind_result<_Result, _Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {}, _Result = void, _Functor = void (*)(int), _Bound_args = {}, std::_Bind_result<_Result, _Functor(_Bound_args ...)>::result_type = void]’

    /usr/include/c++/4.6/thread:117:13:   instantiated from ‘void std::thread::_Impl<_Callable>::_M_run() [with _Callable = std::_Bind_result<void, void (*())(int)>]’

    def_params.cpp:26:9:   instantiated from here

    /usr/include/c++/4.6/functional:1287:4: error: too few arguments to function

Any suggestions or solutions? Thanks in advance!

like image 898
A Frayed Knot Avatar asked Mar 25 '14 22:03

A Frayed Knot


People also ask

How do you pass a parameter to a thread in C++?

Example 1 - Thread Argument Passing long taskids[NUM_THREADS]; for(t=0; t<NUM_THREADS; t++) { taskids[t] = t; printf("Creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]); ... } See the source code.

Can I pass reference to thread C++?

In c++11 to pass a referenceto a thread, we have std::ref(). std::thread t3(fun3, std::ref(x)); In this statement we are passing reference of x to thread t3 because fun3() takes int reference as a parameter. If we try to pass 'x' or '&x' it will throw a compile time error.

Is the default method of passing arguments to a function method?

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

What will happen if passing reference through std :: thread?

If you have used std::thread or std::bind , you probably noticed that even if you pass a reference as parameter, it still creates a copy instead. From cppreference, The arguments to the thread function are moved or copied by value.


1 Answers

thread two (print_int);

You can't do this, default arguments in C++ are only used at the call site (e.g. when you call print_int() yourself) as a syntactic shortcut, but aren't used when e.g. std::thread invokes the same function passed to it as an argument. The problem is std::thread gets given a pointer to a one-argument function, but is not passed an argument to go with it, so it doesn't know how to call it, and there's no way to look up a function's default argument given a pointer to the function.

The simplest solutin is to use a lambda to call the function, as that call can use the default argument:

thread two( []{ print_int(); } );
like image 64
Jonathan Wakely Avatar answered Oct 04 '22 03:10

Jonathan Wakely