5

を使用してスレッドで関数を起動しようとしていますstd::packaged_task

Query query; /* protobuf object */        

/* fill Query object */

std::packaged_task<SearchResults(Query&)> task([](Query& q) ->SearchResults {
    index::core::Merger merger;
    return merger.search(q);
    });

std::future<SearchResults> ftr = task.get_future();
std::thread(std::move(task),query).detach();

Edit2: コードを再度更新してエラーを修正し、完全なエラー メッセージを含めました。

g++-4.6 (Ubuntu 10.04 上) はコードをコンパイルできません:

In file included from /usr/include/c++/4.6/memory:80:0,
              from ../src/net/QueryConnection.cpp:8:
/usr/include/c++/4.6/functional: In instantiation of ‘std::_Bind_result<void, 
std::packaged_task<SearchResults(Query&)>(Query)>’:
/usr/include/c++/4.6/thread:135:9:   instantiated from ‘std::thread::thread(_Callable&&, 
_Args&& ...) [with _Callable = std::packaged_task<SearchResults(Query&)>, _Args = 
{Query&}]’
../src/net/QueryConnection.cpp:77:36:   instantiated from here
/usr/include/c++/4.6/functional:1365:7: error: ‘std::_Bind_result<_Result, 
_Functor(_Bound_args ...)>::_Bind_result(const std::_Bind_result<_Result, 
_Functor(_Bound_args ...)>&) [with _Result = void, _Functor =   
std::packaged_task<SearchResults(Query&)>, _Bound_args = {Query}, 
std::_Bind_result<_Result, _Functor(_Bound_args ...)> = std::_Bind_result<void, 
std::packaged_task<SearchResults(Query&)>(Query)>]’ declared to take const reference, 
but implicit declaration would take non-const
Build error occurred, build is stopped

これはおそらくバグによるものだと読みました: gcc-mailinglist

私は C++ / C++11 を初めて使用します - 適切に機能する代替手段は何ですか? 私は未来を与えるスレッドを起動する必要があるだけですget().who -methodは後でboost::asio非同期ループで呼び出されます。

4

3 に答える 3

3

これは GCC 4.6 のバグ (実際には C++11 標準の欠陥) であり、4.7 で既に修正されています。

あなたが使用できる回避策としてstd::async

Query query;
std::future<SearchResults> ftr = std::async([](Query& q) ->SearchResults {
      index::core::Merger merger;
      return merger.search(q);
    }, query);

packaged_taskこれは GCC 4.6 で問題なく動作し、いずれにせよ を作成して切り離されたスレッドで実行するよりも簡単で安全です。

于 2012-06-07T21:28:20.747 に答える
1

これらが GCC のエラーの原因かどうかはわかりませんが、それでも問題があります。

[=](Query& q){
        index::core::Merger merger;
        return merger.search(q);
}

このラムダは単一の return ステートメントで構成されておらず、明示的な戻り値の型が指定されていないため、void戻り値の型があります。オブジェクトを返すことを意図していたと思われSearchResultsます。また、Query&パラメーターを受け取るため、パッケージ化されたタスクの適切な署名はSearchResults(Query&).

[=](Query& q) -> SearchResults {
        index::core::Merger merger;
        return merger.search(q);
}
于 2012-06-07T18:44:36.533 に答える
0

更新されたコードには2つの問題があります。

1)ラムダはそれがリターンタイプであると正しく述べていません。必要な構文は次のとおりです(ローカル変数をコピーする必要がないと仮定):

[](Query& q) -> SearchResults {
        index::core::Merger merger;
        return merger.search(q);
}

2)パッケージ化されたタスクにが必要な場合、タスクに渡すことができるように、コンストラクター Query&への2番目の引数として非定数クエリへの参照を渡す必要があります。std::thread

私が思い出せないのは、定数以外のクエリ参照を2番目の引数として合法的に渡すことができるstd::threadかどうか、または2番目の引数を参照によって適切に渡すように使用する必要があるかどうかですstd::ref(q)

書かれているように、引数なしでタスクを呼び出そうとしています。

/usr/include/c++/4.6/future:1272:7:注:候補者は1つの引数を期待し、0が提供されます

于 2012-06-07T20:48:36.780 に答える