Search code examples
c++c++11boost

Using boost::future with "then" continuations


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");
   });
}

Solution

  • 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 define BOOST_THREAD_PROVIDES_FUTURE if you want to use boost::future. When BOOST_THREAD_VERSION>=3 define BOOST_THREAD_DONT_PROVIDE_FUTURE if you want to use boost::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.