I can't relate with similar questions. That's my MRE, basically I'd like to overload fun
with a version accepting a template reference. It all works until std::thread
enters in the game. It seems I'm missing something from its constructor.
Error shown on g -10 is
error: no matching function for call to ‘std::thread::thread(, std::string, std::shared_ptr)’ 43 | std::make_shared());
#include <string>
#include <memory>
#include <thread>
class MyData
{};
class MySem
{};
template <typename T, typename Sem>
void fun(T & t, const std::string & TAG, std::shared_ptr<Sem> upSem)
{}
template <typename T, typename Sem>
void fun(const std::string & TAG, std::shared_ptr<Sem> upSem)
{
T t;
fun(t, TAG, upSem); // NO std::ref(t)
}
int main(int argc, char ** argv)
{
MyData d;
fun<MyData, MySem>(
"works",
std::make_shared<MySem>());
fun<MyData, MySem>(
d,
"this too",
std::make_shared<MySem>());
std::thread t1(fun<MyData, MySem>,
std::string("this doesn't"),
std::make_shared<MySem>()); // line 43
std::thread t2(fun<MyData, MySem>,
d,
std::string("this neither"),
std::make_shared<MySem>());
return 0;
}
CodePudding user response:
My guess is that the constructor of std::thread
cannot resolve which overload of fun
you're trying to call. No idea why though.
Having only one version of fun
such as
template <typename T, typename sem>
void fun(const std::string&, std::shared_ptr<sem>)
{
...
}
Allows you to construct t1
fine (but t2
will obviously fail).
A workaround is to pass a lambda instead, such as:
std::thread t3([&](){fun<data, sem>(d, "works again", std::make_shared<sem>());});
std::thread t4([&](){fun<data, sem>("this too", std::make_shared<sem>());});
CodePudding user response:
If you have an overloaded function and want to pick a specific overload, you have to cast it manually to get the right one like:
std::thread t1(static_cast<void(*)(const std::string&, std::shared_ptr<MySem>)>(&fun<MyData, MySem>),
std::string("this doesn't"),
std::make_shared<MySem>()); // line 43
As already given in the comment from "Passer By", using a lambda simplifies the whole thing a lot and makes the code more readable.
See also here: other answer
CodePudding user response:
The problem is not related with the std::thread
function, the problem is that the compiler does not know which overloaded function you are requesting, using a lambda as a workaround could do the job:
std::thread t1([=]{
fun<MyData, MySem>(std::string("This doesn't"), std::make_shared<MySem>());
} );
t1.join();