C++ std::async的奇怪行为
考虑以下示例代码:C++ std::async的奇怪行为,c++,gcc,c++11,stdasync,C++,Gcc,C++11,Stdasync,考虑以下示例代码: #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 = s
#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.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...>)
^
在/usr/local/include/c++/4.8.2/future:38:0中包含的文件中,
来自测试。cpp:1:
/usr/local/include/c++/4.8.2/functional:在“struct std::_Bind_simple”的实例化中:
/usr/local/include/c++/4.8.2/future:1525:70:std::future std::async(std::launch,_-Fn&&&,_-Args&&……[with _-Fn=std::array*(&)(std::array&);_-Args={std::array&};typename std::result_of::type=std::array*]
/usr/local/include/c++/4.8.2/future:1541:36:std::future std::async(_Fn&&,_Args&&…[带_Fn=std::array*(&)(std::array&);_Args={std::array&};typename std::result_of::type=std::array*]
测试。cpp:13:30:从这里开始需要
/usr/local/include/c++/4.8.2/functional:1697:61:错误:在“class std::result_of”中没有名为“type”的类型
typedef typename result_of::type result_type;
^
/usr/local/include/c++/4.8.2/functional:1727:9:错误:在“class std::result_of”中没有名为“type”的类型
_M_invoke(_Index_tuple)
^
这似乎是libstdc++的问题
因此,我的问题是:
1-GCC是否应该拒绝此代码,或者标准中是否有我不知道的内容。
2-断言是否失败?预期的行为是,采用相同引用的异步函数应该引用相同的对象,但副本似乎是异步任务的本地副本
我尝试过使用clang进行编译,但它与4.8.2有相同的编译错误问题(因为它共享相同的libstdc++),并且它无法编译4.6.3库头
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 ...;
}
模板
未来异步(F&func、foo\u t&arg){
F本票副本(本票);
foo_t arg_copy(arg);
//关于背景线程
内部设置未来结果(函数复制(标准::移动(参数复制));
返回。。。;
}
std::ref(foo)
,则断言不应失败。如果代码没有编译,那就没有意义了请对这些部分添加更多解释:“std::async复制参数”和“不能将右值绑定到左值引用”。我相信你是对的,但是这个答案,就像现在这样,让我困惑。谢谢。这似乎是一个非常罕见的C++例子,它比你更了解…有人会认为他们会使用完美的转发,并假设用户知道他们在做什么。无论如何,编译错误是相当迟钝的。谢谢你的澄清。
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 ...;
}