Home > Back-end >  no matching function for call to <unresolved overloaded function type>
no matching function for call to <unresolved overloaded function type>

Time:03-17

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();
  • Related