簡體   English   中英

std :: async的奇怪行為

[英]Odd behavior with std::async

考慮以下示例代碼:

#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庫標頭。

  1. 是的,gcc應該拒絕此代碼。 std::async復制參數並將其作為右值轉發。 您不能將右值綁定到左值引用,因此失敗。 如果要通過引用傳遞,請使用std::ref(foo) 在此特定示例中,對std::async(bar,foo)的調用實質上執行以下操作:

     template<typename F> future<foo_t*> async(F& func,foo_t& arg){ F func_copy(func); foo_t arg_copy(arg); // on background thread internal_set_future_result(func_copy(std::move(arg_copy))); return ...; } 
  2. 如果使用std::ref(foo)則斷言不應失敗。 如果代碼無法編譯,那將是一個有爭議的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM