4

私はもともとこの答えを試しましたが、「bind」の値を「int」(この場合は関数の戻り型)に割り当てるときにコンパイルエラーが発生しました。私はブーストにかなり慣れていませんが、改善しようとしています。以下をコンパイルしてVC10で正しく動作させる方法に関する提案はありますか?

template <class T, class F>
void ExecuteWithReturn(const F &_bind, long sleep, T & ret)
{
    ret = _bind();
}

template <class T, class F>
bool TryExecuteFor(const F &_bind, long sleep, T & ret) {
    boost::thread thrd(ExecuteWithReturn<T, F>, _bind, boost::ref(ret));
    return thrd.timed_join(boost::posix_time::milliseconds(sleep));
}

この結果、コンパイルエラーが発生します。

エラーC2198:'void(__cdecl *)(const boost :: _ bi :: bind_t&、long、T&)':1> [1>
R = long、1> F = long(__cdecl * )(const wchar_t *、const wchar_t *、wchar_t **)、1>
L = boost :: _ bi :: list3、boost :: _ bi :: value、boost :: _ bi :: value>、1> T = int 1 >]

この関数の使用法は次のようになります。

int ret;
if(!TryExecuteFor(boost::bind(g_pMyFunc, someParam, anotherParam), 10000, ret))
{
   ...
}

編集: ExecuteWithReturnの明白な問題を指摘してくれたFraserに感謝します。別の修正と組み合わせることで、コードが機能するようになりました。実行後、スレッドが孤立していると、関数が戻る前に、渡された変数(戻り値を含む)がスコープ外になる可能性が非常に高いことに気付きました。バインドされたファンクターのパラメーターについてはあまりできませんが、潜在的な問題を軽減するために、戻り値をshared_ptrに変更しました。現在機能している実装は次のとおりです。

template <class F>
void ExecuteWithReturn(const F &_bind, boost::shared_ptr<decltype(_bind())> _ret)
{
    *_ret = _bind();
}

template <class F>
bool TryExecuteFor(const F &_bind, long _timeout, boost::shared_ptr<decltype(_bind())> _ret) {
    boost::thread thrd(ExecuteWithReturn<F>, boost::ref(_bind), _ret);
    return thrd.timed_join(boost::posix_time::milliseconds(_timeout));
}

簡単なTODOは、値を返さない関数のオーバーロードになりますが、基本的なテストの後、期待どおりに機能します。

4

1 に答える 1

4

あなたは単に余分な議論を持っていますExecuteWithReturn

関数はおそらく次のように変更する必要があります

void ExecuteWithReturn(const F &_bind, T & ret)

または、sleep呼び出す場所にパラメータを渡す必要がありExecuteWithReturnます。

boost::thread thrd(ExecuteWithReturn<T, F>, _bind, sleep, boost::ref(ret));
于 2013-03-19T02:57:27.890 に答える