2016-07-13 27 views
0

私は2つのレガシーコードを改造しようとしています。ピースの1つは、関数呼び出しのタイムアウトを実装します。これまでのところ、C++のメソッドに使用され、完全に機能しています。r値参照としてC関数とパラメータを渡す

古いCライブラリと同様のタイムアウトを実装する必要があります。私はこれに同じコードを使用しようとしていますが、問題にぶつかっています。

ここでは、私が直面している問題のコードの簡略版です。

uint32_t myFunc1() 
{ 
    return 0; 
} 

uint32_t myFunc2(uint32_t a) 
{ 
    return a; 
} 

int main() 
{ 
    uint32_t dummy = 1; 
    timedCall(myFunc1); //compiles fine. 
    timedCall(myFunc2, dummy); //compile errors C2672, C2893 
} 

template <class F, class... Args> 
uint32_t timedCall(F &&f, Args&&... a) 
{ 
    try 
    { 
     std::packaged_task<uint32_t(Args...)> myTask(std::bind(f, a...)); 
     auto res = myTask.get_future(); 
     std::thread(std::move(myTask), a...).detach(); //This is where the issue is.   

     //Do other stuff 
    } 
    catch(...) 
    { 
     //handle exceptions 
    } 

    return 0; //return something 
} 

私は次のエラーを取得:

C2672 'std::invoke': no matching overloaded function found 
C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)' 

誰かが私が間違ってやっているものを私に教えてもらえますし、それを修正する方法?あなたはobj()で呼び出すことができます呼び出し可能オブジェクトを取得std::bind(f, a...)使用するときに私は、Visual Studio 2015

+0

あなたは減らすことができますstd::asyncがあなたのためにはるかに簡単にタスクを行いますが、エラーを生成するために必要なkeastまでコード化しますか?どのような正確なバージョンのmsvcを使用していますか?その他のエラーメッセージはありませんか?通常は文脈を与える。 – Yakk

+0

C++ 11またはC++ 14モードでClangとコンパイルしても問題ありません。 –

+0

@Yakk、申し訳ありませんが、より具体的なはずです。私はVisual Studio 2015を使用しています。 – Amol

答えて

1

アコンカグアソリューション従うために::スレッドはpackaged_taskを受け付けません。std::thread(f, a...)は正常に動作しました。今私はstd::thread海域で出荷しようとしないだろう(編集:アンドレイ・R.は何が悪かったのかを詳細に良い説明を提供):

template <class F, class... Args> 
uint32_t timedCall(F &&f, Args&&... a) 
{ 
    try 
    { 
     auto res = std::async 
     (
      std::launch::async, 
      std::forward<F>(f), 
      std::forward<Args>(a)... 
     ); 
     //Do other stuff 
    } 
    catch(...) 
    { 
     //handle exceptions 
    } 

    return 0; //return something 
} 
+0

ありがとう!それはたくさんの助けになりました! – Amol

1

を使用しています。しかし、std::packaged_task<uint32_t(Args...)>のコンストラクタでは、obj(a...)で呼び出し可能なオブジェクトが必要です。しかし、コンパイラの中には余分な引数を無視するものもあります。

あなたはどちらかbindを削除する必要があります。

std::packaged_task<uint32_t(Args...)> myTask(f); 
auto res = myTask.get_future(); 
std::thread(std::move(myTask), std::forward<Args>(a)...).detach(); 

または呼び出し構文を変更するには:

std::packaged_task<uint32_t()> myTask(std::bind(f, std::forward<Args>(a)...)); 
auto res = myTask.get_future(); 
std::thread(std::move(myTask)).detach(); 

または(より良い)問題がSTDである

+1

std :: forwardを最初のソリューションに追加することをお勧めします。 – Aconcagua

+0

説明をありがとう。これは、私が今継承したこのコードで何が起こっているのか理解する助けになりました。 – Amol

関連する問題