当类具有 std::mutex 成员时,异步调用成员函数时出错

Hui Liu-MSFT 48,676 信誉分 Microsoft 外部员工
2024-03-14T05:48:55.3166667+00:00

你好

下面的代码编译并成功运行,Foo 的计算方法可以使用 std::async 同步调用和异步调用。

#include <iostream>
#include <future>

struct Foo
{
    int compute()
    {
        return 123;
    }

    // === UNCOMMENT THE LINE BELOW TO SHOW THE ERROR ===
    //std::mutex the_mutex;
};

int main()
{
    Foo foo;
    std::cout << "result: " << foo.compute() << std::endl;

    std::future<int> f = std::async(std::launch::async, &Foo::compute, foo);
    std::cout << "result: " << f.get() << std::endl;

    return 0;
}

但是,如果取消注释 std::mutex 成员,编译将失败,并出现以下错误:

错误 C2661 “std::tuple<int (__thiscall Foo:: )(void),Foo>::tuple”:没有重载函数接受 2 个参数*

此外,如果您注释掉异步调用该方法的代码,错误就会消失,我使用的是 VS2019 v16.7.4。请注意,这不是 std::mutex 本身的问题。如果我用 boost::asio::io_context 成员变量替换它,我可以看到相同的行为。

我已经很久没有做过C++编程了。假设这不是编译器错误,我想了解原因并找到解决方法。

谢谢
Note:此问题总结整理于 : Issue invoking member function asynchronously when class has a std::mutex member

开发人员技术 C++
0 个注释 无注释
{count} 票

接受的答案
  1. 匿名
    2024-03-14T09:05:06.82+00:00

    你好

    std::mutex 是不可复制的。因此,包含它的 Foo 类变得不可复制。您正在将一个临时的 Foo 对象传递给 std::future,并且您可能希望在所有线程中使用相同的对象。我建议您可以使用 std::ref 来传递对现有对象的引用。

    代码如下:

    #include <iostream>  
    #include <future>  
      
    struct Foo  
    {  
    	int compute()  
    	{  
    	return 123;  
    	}  
      
    	// === UNCOMMENT THE LINE BELOW TO SHOW THE ERROR ===  
    	std::mutex the_mutex;  
    };  
      
    int main()  
    {  
    	Foo foo;  
    	std::cout << "result: " << foo.compute() << std::endl;  
      
    	std::future<int> f = std::async(std::launch::async, &Foo::compute, std::ref(foo));  
    	std::cout << "result: " << f.get() << std::endl;  
      
    	return 0;  
    }  
    

    如果答案是正确的,请点击“接受答案”并点赞。 如果您对此答案还有其他疑问,请点击“评论”。

    注意:如果您想接收相关电子邮件,请按照我们的文档中的步骤启用电子邮件通知 此线程的通知。

    0 个注释 无注释

0 个其他答案

排序依据: 非常有帮助

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。