次のサンプル コードを検討してください。
#include <future>
#include <array>
#include <cassert>
typedef std::array<int, 5> foo_t;
foo_t* bar(foo_t& foo) {
return &foo;
}
int main() {
foo_t foo;
auto a = std::async(bar, foo);
auto b = std::async(bar, foo);
assert(a.get() == b.get());
return 0;
}
GCC 4.6.3 はこれを問題なくコンパイルします。ただし、これは実行時に次のように失敗します。
test: test.cpp:15: int main(): Assertion `a.get() == b.get()' failed.
Aborted (core dumped)
ただし、GCC 4.8.2 はファイルのコンパイルを拒否します。
In file included from /usr/local/include/c++/4.8.2/future:38:0,
from test.cpp:1:
/usr/local/include/c++/4.8.2/functional: In instantiation of 'struct std::_Bind_simple<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>':
/usr/local/include/c++/4.8.2/future:1525:70: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = std::array<int, 5ul>* (&)(std::array<int, 5ul>&); _Args = {std::array<int, 5ul>&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = std::array<int, 5ul>*]'
/usr/local/include/c++/4.8.2/future:1541:36: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::array<int, 5ul>* (&)(std::array<int, 5ul>&); _Args = {std::array<int, 5ul>&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = std::array<int, 5ul>*]'
test.cpp:13:30: required from here
/usr/local/include/c++/4.8.2/functional:1697:61: error: no type named 'type' in 'class std::result_of<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/local/include/c++/4.8.2/functional:1727:9: error: no type named 'type' in 'class std::result_of<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>'
_M_invoke(_Index_tuple<_Indices...>)
^
これは libstdc++ の問題のようです。
したがって、私の質問は次のとおりです。1-GCCはこのコードを拒否する必要がありますか、それとも標準に私が知らない何かがありますか。2 - アサーションは失敗しますか? 予想される動作は、同じ参照を取る非同期関数が同じオブジェクトを参照する必要があることですが、コピーが非同期タスクに対してローカルに作成されているようです。
clang でコンパイルしようとしましたが、4.8.2 と同じコンパイル エラーの問題があり (同じ libstdc++ を共有しているため)、4.6.3 ライブラリ ヘッダーをコンパイルできません。