0

为什么不让这样的线程在抽象基类中工作?我试图为从这个基类派生的用户抽象出所有的多线程细节。callbackSquare当我清楚地写出返回 type时,我不明白为什么它说“没有名为'type'的类型” int

#include <iostream>
#include <future>
#include <vector>

class ABC{
public:
    std::vector<std::future<int> > m_results;
    ABC(){};
    ~ABC(){};
    virtual int callbackSquare(int& a) = 0;
    void doStuffWithCallBack();
};

void ABC::doStuffWithCallBack(){
    for(int i = 0; i < 10; ++i)
        m_results.push_back(std::async(&ABC::callbackSquare, this, i));

    for(int j = 0; j < 10; ++j)
        std::cout << m_results[j].get() << "\n";
}

class Derived : public ABC {
    Derived() : ABC() {};
    ~Derived(){};
    int callbackSquare(int& a) {return a * a;};
};

int main(int argc, char **argv)
{

    std::cout << "testing\n";

    return 0;
}

我得到的奇怪错误是:

/usr/include/c++/5/future:1709:67:   required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/usr/include/c++/5/future:1725:19:   required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/home/taylor/Documents/ssmworkspace/callbacktest/main.cpp:16:69:   required from here
/usr/include/c++/5/functional:1505:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/5/functional:1526:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
         _M_invoke(_Index_tuple<_Indices...>)
4

1 回答 1

5

您的问题可以通过任何接受引用的函数重现:

#include <future>

int f(int& a)
{
    return a * a;
}

int main()
{
    int i = 42;
    auto r = std::async(f, i);
}

接受代码中的引用是有风险的,因为变量将被循环迭代修改,创建数据竞争,因为被调用的函数也访问变量。

更改函数以按值接受输入参数,或std::async通过传递std::ref(i)或调用std::cref(i)(如果函数接受 const 引用)如果您承认风险。

于 2017-10-14T19:26:16.603 回答