调用 std::线程,指针指向独立函数
Invoking std::thread with pointer to freestanding function
我试图用指向函数的指针(而不是指向成员函数的指针)调用std::thread
完美的转发构造函数(template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
),如以下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();
}
现场演示:https://godbolt.org/g/Cwi6wd
为什么代码不能在GCC,Clang和MSVC上编译,抱怨缺少invoke
(或类似名称)的过载?函数参数是指向函数的指针,所以它应该是一个Callable
,对吧?
请注意:我知道使用 lambda 可以解决问题;我想了解为什么会出现这个问题。
std::thread
存储它所传递的参数的副本。正如马西米利亚诺·简斯(Massimiliano Janes)指出的那样,这是在临时呼叫者的背景下进行评估的。出于所有意图和目的,最好将其视为 const 对象。
由于 x
是非常量引用,因此它不能绑定到线程提供给它的参数。
如果要x
引用i
,则需要使用 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();
}
现场示例
实用程序std::ref
将动态创建它。
std::thread 构造函数在调用可调用的参数之前对其参数执行decay_copy - 将结果转发给它;在你的 foo 中,你试图将左值引用 (int&x) 绑定到右值引用(临时),因此出现错误;要么采用 int、int const&或 int&& 代替(或传递引用包装器)。
继StoryTeller的回答之后,lambda可能会提供一种更清晰的方式来表达这一点:
我认为有几种情况:
如果我们确实想在外部作用域中传递对i
的引用:
auto thd = std::thread([&i]
{
foo("bar", i);
});
如果 foo 引用恰好是一个历史事故:
auto thd = std::thread([]() mutable
{
int i = 1;
foo("bar", i);
});
在第二种形式中,我们本地化了变量i
,并降低了它被读取或写入线程外部(即 UB)的风险。
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- 为什么C++哈希函数的返回类型是 std::size_t,而不是独立于平台的类型?
- 为什么"C++ Core Guidelines"推荐首选独立函数而不是类成员?
- Doxygen不会为独立函数生成文档
- 从独立函数中调用成员函数
- 定义可以执行对象方法和独立函数的函数时出现问题
- 在每个实例中,使成员函数中的静态变量独立
- 独立于元素内存管理的向量上的函数
- 调用 std::线程,指针指向独立函数
- 创建独立于构造函数的对象指针
- DBUS 代码在放置在守护进程内时崩溃,但在没有守护进程代码的独立独立 main() 函数中运行良好
- 为什么std::whatever::erase()是一个方法,std::remove()是独立函数
- 获得快速的k对独立散列函数的选项是什么
- 如何使用独立于索引的函数初始化向量
- 如何在C++上独立运行函数
- 调用需要具有结构的独立参数的 C++ 函数是否安全
- Visual Studio 2010-独立函数中存在链接器错误
- c++如何将成员函数一般地转换为独立函数(用作函数参数)
- 如何从独立函数中输入数据到数组中
- 推导独立函数的返回类型