为什么我们可以直接将函数对象推送到std::thread



我有点困惑为什么我们可以做这样的事情:

std::vector<std::thread> vec;
vec.reserve(2);
vec.emplace_back(std::bind(silly, 1));
vec.emplace_back(std::bind(silly, 2));
for (auto i = 0; i < vec.size(); i++) {
vec[i].join();
}
// for folks who see this post after
// you can use push_back() like this:
vec.push_back(std::thread(std::bind(silly, 3)));

在上面的代码中,我们直接将函数对象推送到线程向量,我不知道为什么它是可以接受的。因为根据我的知识,线程向量只能将线程类型的对象推送给它。就像int向量一样,我们只能将int类型的对象推向它。

下面的例子是我可以100%理解的,因为我们将线程对象推到线程向量中!

std::vector<std::thread> vecOfThreads;
std::function<void()> func = []() {
//Do Some Important Work
// .....
//Print Thread ID
std::cout << "From Thread ID : " << std::this_thread::get_id() << "n";
};
vecOfThreads.push_back(std::thread(func));
std::thread th1(func);
vecOfThreads.push_back(std::move(th1));
for (std::thread &th: vecOfThreads) {
// If thread Object is Joinable then Join that thread.
if (th.joinable())
th.join();
}

对于研究这一部分的任何解释和建议材料,我们将不胜感激!

编辑: 我读错了代码示例,如注释所述,在emplace_back的这种特殊情况下,调用构造函数时不经过隐式转换链,这也是template_back的目的。尽管如此,由于问题是关于推动的,所以离开其余部分

C++提供了隐式转换,这使您能够执行以下操作:

double a = 0;

由于将int文本(0(分配给双类型变量(a(,因此不会出现错误。

上面的链接可以为您提供关于隐式转换的详细解释,但我们感兴趣的部分是:

用户定义的转换由零个或一个非显式单参数转换构造函数或非显式转换函数调用组成

std::thread文档中,有一个构造函数接受std::函数(以及可选的参数(,因此,如果链的其余部分得到尊重,它可以在推送线程向量时用于自动将函数转换为线程(显然不是(。在您的代码示例中,它是在没有隐式转换限制的情况下直接调用的。

最新更新