Pracka
Pracka

Reputation: 159

Does std thread constructor take variadic thread function?

I am trying to pass a variable count of callback functions (all of the same signature) to a thread function. I came up with the following code

using namespace std;

void callback(int i)
{
    cout<<"thread "<<i<<" running"<<endl;
}

template<typename ...CallbackType>
void threadProc(int id, CallbackType ...callbackPack)
{
    auto callbacks = {callbackPack...};
    for(auto callback : callbacks)
    {
        callback(id);
    }
}

int main()
{
    thread t(threadProc<void(int)>, 1, callback);
    t.join();
    return 0;
}

This code fails to compile with

error: no matching function for call to ‘std::thread::thread(, int, void (&)(int))’
 thread t(threadProc<void(int)>, 1, callback);

Things would work fine if threadProc() is not using any parameter pack. Is there a correct way to launch a thread with variadic thread function?

Upvotes: 1

Views: 190

Answers (2)

Brian Bi
Brian Bi

Reputation: 119239

There is nothing wrong with your code. This seems to just be a bug in GCC, which has nothing to do with threads. A minimal test case that reproduces the bug is:

template <typename... T>
void foo(T...) {}

int main()
{
    auto* pfoo = foo<void(int)>;

    return 0;
}

It seems that GCC does not like the fact that foo has a parameter of type void(int). Yet the rules of the language are clear: this is allowed, and the function type is adjusted to the corresponding function pointer type when it appears as a parameter type.

Other compilers seem to have no issue with it. See https://godbolt.org/z/tgaV7B

As a workaround, you can write:

thread t(threadProc<void(*)(int)>, 1, callback);

Or:

thread t(threadProc<decltype(&callback)>, 1, callback);

Upvotes: 1

asmmo
asmmo

Reputation: 7100

your first argument is a function pointer, hence use

thread t{threadProc<void(*)(int)>, 1, callback};

Here https://godbolt.org/z/Hzp9EP

Upvotes: 3

Related Questions