C ++ - 在std :: thread中调用重载函数时编译失败

时间:2017-05-18 13:40:30

标签: c++

考虑以下情况:

// utils.h

#include <string>
#include <list>

namespace Utils {
    void do_something(int a, std::list<int> *b);
    void do_something(int a, std::list<std::string> *b);
};

// utils.cpp

#include "utils.h"

void Utils::do_something(int a, std::list<int> *b) {

}

void Utils::do_something(int a, std::list<std::string> *b) {

}

// main.cpp

#include <thread>
#include <list>
#include "utils.h"

int main() {
    std::list<int> list;
    std::thread t(Utils::do_something, 17, &list);
    t.join();
    return 0;
}

当我编译它时,我收到以下错误:

error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, int, std::list<int>*)'

知道我做错了什么吗?在我添加获得std::list<std::string>*的重载函数之前,它确实编译好了。

2 个答案:

答案 0 :(得分:4)

这里的问题是,即使您将参数传递给std::thread,它也不会使用这些参数来尝试确定传递给它的函数。它试图孤立地解决函数类型。当它这样做时,它会看到有两个不同的版本,所以它停止,因为它不知道你想要哪一个。

不幸的是,您将不得不告诉编译器您要使用哪个函数。您可以通过将函数转换为所需的特定函数指针来实现。

不是这样做,而是通过允许重载解析在常规函数调用(如

)中使用lambda来实现这一点。
std::thread t([](auto first, auto second){ return Utils::do_something(first, second); }, 17, &list);

这也适用于成员函数,因为您只需捕获对象以使用lambda的捕获列表调用函数。这样您就不必将该对象传递给std::thread或使用std::bind

答案 1 :(得分:3)

您可以使用static_cast消除重载的歧义......

std::thread t(static_cast<void(*)(int, std::list<int> *)>(&Utils::do_something), 17, &list);