如何将此 std::function 传递给 std::async

Posted

技术标签:

【中文标题】如何将此 std::function 传递给 std::async【英文标题】:How can I pass this std::function to std::async 【发布时间】:2019-08-15 13:21:01 【问题描述】:

我正在处理一段多线程代码,但我似乎无法将 std::function 对象传递给 std::async 函数。我确定我做错了什么,但我不知道那会是什么。因此,我准备了这段代码,希望知道的人可以帮助我。

Test1 证明这个 std::function 对象有效。 Test2 包含我想要它做的事情;只有我将函数对象包装成 lambda。 Test3 包含我无法弄清楚的示例。

std::function<void(AsyncFunctionExample&)> current_function;

void Test1() 
  current_function = &AsyncFunctionExample::Function1;
  while(current_function != nullptr)
    current_function(*this);


void Test2() 
  current_function = &AsyncFunctionExample::Function1;
  while(current_function != nullptr)
    const std::future<void> function_future = std::async([&]()current_function(*this););


void Test3() 
  current_function = &AsyncFunctionExample::Function1;
  while(current_function != nullptr)
    const std::future<void> function_future = std::async(current_function, *this);

可以在here 找到此示例的完整代码。 *** 编辑器警告说我不允许转储完整的代码文件,所以我在这里将其归结为基本内容。

我收到的编译器错误是: 没有匹配的函数调用'async(std::function&, AsyncFunctionExample&)' const std::future function_future = std::async(current_function, *this);

这对我帮助不大。它基本上向我解释了没有与我的电话匹配的签名。但我无法从这个错误中找出我的调用的哪一部分是错误的,我不明白如何更改它以使其正常工作。

【问题讨论】:

Test2 是做你想做的事的方式。 似乎 Test3 应该是可能的。这个问题涉及一个类似的主题,它在那里工作:***.com/questions/19079179/… 但也许我缺少一些东西。如果有请解释。 什么current_function?请创建minimal reproducible example 向我们展示。当询问构建错误时,请包括 fullcomplete 错误输出,包括可能的信息说明。完整的错误输出可能包含有关问题的提示。 另外,为什么循环while(current_function != nullptr)?在示例中,您表明循环没有意义。 请注意,除非您将future 存储在某处或在循环结束之前执行其他操作(其中function_future 将被销毁),否则std::async 的返回值的销毁将阻塞,直到功能完成。实际上,它不会是异步的。 【参考方案1】:

您不能通过std::async 传递引用,因为它需要复制值。您可以使用std::ref 解决此问题:

const std::future<void> function_future = std::async(current_function, std::ref(*this));

或者,只需将您的功能更改为:

std::function<void(AsyncFunctionExample*)> current_function;

那你可以直接传this

const std::future<void> function_future = std::async(current_function, this);

【讨论】:

我们有一个赢家;非常感谢你!你能解释一下我自己是怎么想出来的吗? @MaestroMaus ...通过学习和经验。在做了几年的工作后,你会注意到你自己(或谷歌)无法解决的问题变得更加复杂。 (这就是学习的效果。)或者,您只是使用更简单的解决方案来解决您的问题。 (这就是经验的影响。);-) @MaestroMaus 是的,只是体验一下,如果你想一想std::async 必须如何实现,那么显然它需要复制或移动它的参数。然后你会记得你尝试传递std::bind 或类似的引用的所有时间,并记得必须包含std::ref。当然,对于 c++11,您几乎不需要再使用std::bind,因此遇到std::ref 的机会更少

以上是关于如何将此 std::function 传递给 std::async的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]

如何在 std::function 的参数中进行可变参数推导?

第11课 std::bind和std::function_std::bind绑定器

c++ std::bind 如何返回分配给 std::function 的值?

C ++:如何将此指针传递给此类?

错误“lambda 不是从 'std::function' 派生的