私はもともとこの答えを試しましたが、「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は、値を返さない関数のオーバーロードになりますが、基本的なテストの後、期待どおりに機能します。