I tried to invoke std::thread
perfect forwarding constructor (template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
) with a pointer to function (NOT a pointer to member function), as shown in the following M(N)WE:
#include <thread>
#include <string>
static void foo(std::string query, int & x)
{
while(true);
}
int main() {
int i = 1;
auto thd = std::thread(&foo, std::string("bar"), i);
thd.join();
}
Live demo: https://godbolt.org/g/Cwi6wd
Why does the code not compile on GCC, Clang and MSVC, complaining about a missing overload of invoke
(or similar names)?
A function argument is a pointer to a function, so it should be a Callable
, right?
Please note: I know that using a lambda would solve the problem; I want to understand why the problem arises.
std::thread
stores copies of the arguments it is passed. Which as Massimiliano Janes pointed out, is evaluated in the context of the caller to a temporary. For all intents and purposes, it's better to consider it as a const object.
Since x
is a non-const reference, it cannot bind to the argument being fed to it by the thread.
If you want x
to refer to i
, you need to use std::reference_wrapper
.
#include <thread>
#include <string>
#include <functional>
static void foo(std::string , int & )
{
while(true);
}
int main() {
int i = 1;
auto thd = std::thread(foo, std::string("bar"), std::ref(i));
thd.join();
}
Live Example
The utility std::ref
will create it on the fly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With