绑定对象函数时的c ++异步错误

时间:2018-01-12 07:26:10

标签: c++ asynchronous

最近,我在绑定对象函数时遇到了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);

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

1 个答案:

答案 0 :(得分:1)

问题在于,您无法将引用作为参数传递给具有std::asynch(或使用std::threadstd::bind且可能更多的函数的函数。您必须使用std::ref来包装引用参数:

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

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

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

最后,对于没有产生结果的东西来说,延期的未来真的没什么意义,只打印一些东西。