最近,我在绑定对象函数时遇到了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);
但是,这不是一种有效的方法,因为整个对象只是复制到函数中。 我想知道是否有任何其他方法可以修复此错误,而无需修改引用类的参数类型。
答案 0 :(得分:1)
问题在于,您无法将引用作为参数传递给具有std::asynch
(或使用std::thread
或std::bind
且可能更多的函数的函数。您必须使用std::ref
来包装引用参数:
std::async(launch::deferred, &C::multi_get, this, std::ref(a), std::ref(b));
考虑到被调用函数没有修改传递的参数,它应该使用const
引用,在这种情况下必须使用std::cref
。
您也可以通过值传递,如果实际结构的复制成本很高,则使用移动语义。
最后,对于没有产生结果的东西来说,延期的未来真的没什么意义,只打印一些东西。