我想将boost::future
与延续boost::when_all
/ boost::when_any
一起使用。
Boost trunk - 不是1.55 - 包括后者的实现(以提案here为模型,即将推出C ++ 14/17和Boost 1.56)。
This就是我所拥有的(它不会编译):
#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#include <boost/thread/future.hpp>
using namespace boost;
int main() {
future<int> f1 = async([]() { return 1; });
future<int> f2 = async([]() { return 2; });
auto f3 = when_all(f1, f2);
f3.then([](decltype(f3)) {
std::cout << "done" << std::endl;
});
f3.get();
}
Clang 3.4用this纾困 - 这是一段摘录:
/usr/include/c++/v1/memory:1685:31: error: call to deleted constructor of 'boost::future<int>'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
我做错了还是这个错误?
答案 0 :(得分:6)
问题是只能使用右值when_all
或future
调用shared_future
。来自N3857:
template <typename... T> see below when_all(T&&... futures);
要求:
T
的类型为future<R>
或shared_future<R>
。
由于引用折叠规则,传递左值会导致T
被推断为future<T>&
,违反了规定的要求。 boost实现不会检查这个前提条件,因此你会在模板代码深处得到一个错误,其中rvalue future的移动将转变为左值未来的尝试副本。
您需要将期货移至when_all
参数:
auto f3 = when_all(std::move(f1), std::move(f2));
或者首先避免命名它们:
auto f = when_all(async([]{return 1;}),
async([]{return 2;}));
此外,您必须get
从then
而不是中间未来返回未来:
auto done = f.then([](decltype(f)) {
std::cout << "done" << std::endl;
});
done.get();
因为您调用then
的未来将被移动到延续的参数中。来自N3857中then
的描述:
后置条件:
- 原来
将
future
对象移动到延续函数的参数valid() == false
对象返回后立即
future
每30.6.6 [futures.unique_future] / 3:
在
valid
对象上调用除析构函数,移动赋值运算符或future
以外的任何成员函数的效果,其中valid() == false
未定义。
你可以通过避免命名期货来避免c ++ 14中的大多数问题:
when_all(
async([]{return 1;}),
async([]{return 2;})
).then([](auto&) {
std::cout << "done" << std::endl;
}).get();