2017-10-14 2 views
0

なぜこのようなスレッドは抽象基本クラスの内部で動作しないのですか?私は、この基本クラスから派生したユーザーのマルチスレッドの詳細をすべて抽象化しようとしています。 callbackSquareの返品タイプintを明記すると、「タイプが「タイプ」ではない」という理由が分かりません。私は取得しています抽象基本クラス内でC++ 11のstd :: asyncを使用する

#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...>) 
+0

"callbackSquare(int&a)' "refで渡す理由はありますか? – curiousguy

+0

[参照によってstd :: asyncに引数を渡すことができません](https://stackoverflow.com/questions/18359864/passing-arguments-to-stdasync-by-reference-fails) – Rakete1111

+0

@curiousguy例。しかし、結局私はもっと大きな引数を渡すでしょう。 – Taylor

答えて

5

あなたの問題は、参照を受け入れるすべての機能を再現することができます:あなたのコード内の参照を受け入れ

#include <future> 

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

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

です変数がループ反復によって変更されてに変更され、呼び出された関数が変数にもアクセスするため、データ競合が作成されるため危険です。

変更関数は値によって入力パラメータを受け入れるか、またはあなたがリスクを認識した場合(関数はconst参照を受け入れる場合)std::ref(i)std::cref(i)を渡すことによってstd::asyncを呼び出します。

関連する問題