最近,我在绑定对象函数时遇到了c ++异步错误。
使用异步时,正常功能可以正常测试。
但是,当我尝试使用类作为参数绑定功能时,就会出现错误。
以下是代码:

class_asy.h

#ifndef CLASS_ASY_H_INCLUDE
#define CLASS_ASY_H_INCLUDE


#include <future>

class A
{
public:
  A(int i_id):id(i_id) {}
  ~A(){}

  int id;

};



class B
{
public:
  B(int i_id):id(i_id) {}
  ~B(){}

  int id;

};

class C
{
public:
  C(){}
  ~C(){}

  // a non-optimized way of checking for prime numbers:
  void multi_get(A& a, B& b);
  std::future<void> setup(A& a, B& b);

};
#endif


然后是class_asy.c:

// async example
#include <iostream>       // std::cout
#include <future>         // std::async, std::future
#include "class_asy.h"

using namespace std;


// a non-optimized way of checking for prime numbers:
void C::multi_get(A& a, B& b) {
  cout << "Calculating. Please, wait...\n";
  cout << a.id * b.id << endl;

}


std::future<void> C::setup(A& a, B& b)
{
    std::future<void> fut = std::async(launch::deferred, &C::multi_get, this, a,b);
    return fut;
}




int main ()
{

  A testa(2);
  B testb(3);
  C testc;
  std::future<void> fut = testc.setup(testa, testb);


  // call is_prime(313222313) asynchronously:
  // std::future<void> fut = std::async (launch::deferred, &C::multi_get, &testc, testa,testb);

  std::cout << "Checking for the result.\n";


  fut.wait();

  // if (ret) std::cout << "It is prime!\n";
  // else std::cout << "It is not prime.\n";

  return 0;
}


整个错误消息如下:

@ubuntu:~/cpp_dynamic_invoke_success/stdasync_class_test$ bash compi.sh
In file included from /usr/include/c++/4.8/future:38:0,
                 from class_asy.cpp:3:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (C::*)(A&, B&)>(C*, A, B)>’:
/usr/include/c++/4.8/future:1539:70:   required from ‘std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = void (C::*)(A&, B&); _Args = {C* const, A&, B&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = void]’
class_asy.cpp:19:82:   required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (C::*)(A&, B&)>(C*, A, B)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (C::*)(A&, B&)>(C*, A, B)>’
         _M_invoke(_Index_tuple<_Indices...>)


我找到了一种解决此问题的方法,就是将引用的类类型修改为直接传递的类类型。

void multi_get(A& a, B& b); -> void multi_get(A a, B b);


但是,这不是一种有效的方法,因为整个对象只是复制到函数中。
我想知道是否还有其他方法可以解决此错误,而无需修改引用类的参数类型。

最佳答案

问题是您不能使用std::asynch(或使用std::threadstd::bind以及可能更多)将引用作为参数传递给函数。您必须使用std::ref包装参考参数:

std::async(launch::deferred, &C::multi_get, this, std::ref(a), std::ref(b));




考虑到被调用函数不会修改传递的参数,它可能应使用const引用,在这种情况下必须使用std::cref

您也可以按值传递,如果实际结构的复制成本很高,则可以使用move语义。

最后,对于那些不会产生结果而仅打印出某些内容的东西,推迟未来真的没有多大意义。

关于c++ - 绑定(bind)对象函数时的c++异步错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48221474/

10-11 22:00
查看更多