简体   繁体   English

std :: async的奇怪行为

[英]Odd behavior with std::async

Consider the following sample code: 考虑以下示例代码:

#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 compiles this with no complaints. GCC 4.6.3对此进行了编译,没有任何投诉。 However, this fails at runtime with: 但是,此操作在运行时失败,并显示以下内容:

test: test.cpp:15: int main(): Assertion `a.get() == b.get()' failed.
Aborted (core dumped)

GCC 4.8.2, however, refuses to compile the file: 但是,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...>)
         ^

This appears to be a libstdc++ issue. 这似乎是一个libstdc ++问题。

So my questions are: 1 - should GCC reject this code, or is there something in the standard that I am not aware of. 所以我的问题是:1-GCC应该拒绝此代码,还是该标准中有我不知道的内容。 2 - should the assertion fail? 2-断言应该失败吗? The expected behavior is that async functions that take the same reference should refer to the same object, but it appears that a copy is made local to the async task. 预期的行为是采用相同引用的异步函数应引用相同的对象,但似乎将副本复制到异步任务的本地。

I've tried compiling with clang, but it has the same compile error issues (as it shares the same libstdc++) with 4.8.2, and it can't compile the 4.6.3 library headers. 我曾尝试使用clang进行编译,但是它与4.8.2存在相同的编译错误问题(因为它共享相同的libstdc ++),并且无法编译4.6.3库标头。

  1. Yes, gcc should reject this code. 是的,gcc应该拒绝此代码。 std::async copies the arguments and forwards them as rvalues. std::async复制参数并将其作为右值转发。 You cannot bind an rvalue to an lvalue reference, so this fails. 您不能将右值绑定到左值引用,因此失败。 If you want to pass by reference use std::ref(foo) . 如果要通过引用传递,请使用std::ref(foo) In this specific example, the call to std::async(bar,foo) essentially does the following: 在此特定示例中,对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. If you use std::ref(foo) then the assertion should not fail. 如果使用std::ref(foo)则断言不应失败。 If the code doesn't compile then it's a moot point. 如果代码无法编译,那将是一个有争议的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM