The C++ 11 std::future
lacks a then
method to attach continuations to the future.
The Boost boost::future
provides this, and there is an example (which I can't get running)
I am simply unable to compile:
#include <iostream>
#include <string>
#include <boost/thread/future.hpp>
boost::future<int> join2(const std::string& realm) {
boost::promise<int> p;
p.set_value(23);
return p.get_future();
}
int main () {
boost::future<int> f = join2("realm1");
// here, I'd like to use f.then(..)
f.wait();
std::cout << f.get() << std::endl;
}
When compiling
clang++ -o test5.o -c -std=c++11 -stdlib=libc++ \
-I/home/oberstet/boost_1_55_0 test5.cpp
this bails out with
test5.cpp:30:1: error: unknown type name 'future'
future<int> join(const std::string& realm) {
...
I am feeling stupid;) What is going on? I am using clang 3.4 with libc++ and Boost 1.55 (unmodified vanilla sources from Boost website).
Would be great to get a hint, probably also with an example of how to modify the example using .then(..)
to print out the result.
Solution (kudos @dyp):
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
seems to be required when compiling for C++ 11 (which provides future), but one wants to use Boost future nevertheless.
For actually using continuations, another define is necessary: BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
.
Here is a complete example
#include <iostream>
#include <string>
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#include <boost/thread/future.hpp>
using namespace boost;
int main() {
future<int> f1 = async([]() { return 123; });
future<std::string> f2 = f1.then([](future<int> f) {
std::cout << f.get() << std::endl; // here .get() won't block
return std::string("sgfsdfs");
});
}
Boost.Thread comes in several versions of which you can choose via the BOOST_THREAD_VERSION
macro. Currently, the default is 2
.
Up to version 2 of Boost.Thread, the name boost::unique_future
was used for this class template (compare to boost::shared_future
). Probably because of the standardization of std::future
, more recent versions can use the name boost::future
. Starting with version 3
, boost::future
is the default name.
The selection which name is to be used is done via a preprocessor macro:
When
BOOST_THREAD_VERSION==2
defineBOOST_THREAD_PROVIDES_FUTURE
if you want to useboost::future
. WhenBOOST_THREAD_VERSION>=3
defineBOOST_THREAD_DONT_PROVIDE_FUTURE
if you want to useboost::unique_future
.
From boost docs: unique_future
vs future
So you can either explicitly enable boost::future
by using BOOST_THREAD_PROVIDES_FUTURE
or switch to a more modern version of Boost.Thread by setting BOOST_THREAD_VERSION
to 4
, for example.