On Thu, Jun 27, 2013 at 9:01 PM, Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Le 27/06/13 14:26, Tobias Furuholm a écrit :

I am trying out future<>.then and I am seeing some results that confuses me. I have tried to illustrate this with a few examples. The first example is using a promise together with future<>.then. It generates no output:

  boost::promise<int> promise;
  boost::future<int> fut = promise.get_future();
  promise.set_value(123);

  fut.then([](boost::future<int>& f) {
     std::cout << "The value is: " << f.get() << std::endl;
     return f.get();
  });

  boost::chrono::milliseconds duration(1000);
  boost::this_thread::sleep_for(duration);

Why is fut.then not triggered? (assigning fut.then to another future makes no difference)
I guess you need to call fut.then() before the value is set. I will need to check if this works when the future is not created with async().

It makes no difference.
 


By adding a launch policy I get the output "The value is: 123" which is the output I would expect from all my examples:

  boost::promise<int> promise;
  boost::future<int> fut = promise.get_future();

  promise.set_value(123);

  fut.then(boost::launch::async, [](boost::future<int>& f) {
     std::cout << "The value is: " << f.get() << std::endl;
     return f.get();
  });

  boost::chrono::milliseconds duration(1000);
  boost::this_thread::sleep_for(duration);

Could you tell me the version of BOOST_THREAD_VERSION are you using?

I use  BOOST_THREAD_VERSION=4 



To make this more real, let's move promise.set_value to after .then

  boost::promise<int> promise;
  boost::future<int> fut = promise.get_future();

  fut.then(boost::launch::async, [](boost::future<int>& f) {
     std::cout << "The value is: " << f.get() << std::endl;
     return f.get();
  });

  promise.set_value(123);

  boost::chrono::milliseconds duration(1000);
  boost::this_thread::sleep_for(duration);

This program outputs nothing and never terminates. But when I assign the result of fut.then to another future I get the expected output once again:

  boost::promise<int> promise;
  boost::future<int> fut = promise.get_future();

  boost::future<int> fut2 = fut.then(boost::launch::async, [](boost::future<int>& f) {
     std::cout << "The value is: " << f.get() << std::endl;
     return f.get();
  });

  promise.set_value(123);

  boost::chrono::milliseconds duration(1000);
  boost::this_thread::sleep_for(duration);

Where is the assignment?
 
I made the assignment bold to make it more visible...
 
Again I will need to check this.

Finally, as I bonus I add an example where I use async to generate a future instead.

  boost::future<int> fut = boost::async([]() { return 123; });

  fut.then([](boost::future<int>& f) {
     std::cout << "The value is: " << f.get() << std::endl;
     return f.get();
  });

  boost::chrono::milliseconds duration(1000);
  boost::this_thread::sleep_for(duration);

future::get() can be called only once depending on the value of BOOST_THREAD_VERSION

This generates the output "The value is: " (without 123). Once again, by assigning the result of fut.then to another future I get the expected output.

I use boost 1.54 beta 1 with clang 3.2 on Linux and.

Please, could you provide complete examples, and the command line?

The examples are complete except for includes and that they are put in a main function. So e.g. the first example looks like this when complete

#include <boost/thread.hpp>

int main()
{
   boost::promise<int> promise;
   boost::future<int> fut = promise.get_future();
   promise.set_value(123);

   fut.then([](boost::future<int>& f) {
      std::cout << "The value is: " << f.get() << std::endl;
      return f.get();
   });

   boost::chrono::milliseconds duration(1000);
   boost::this_thread::sleep_for(duration);
}

The command line follows:

clang++ -m32 --std=c++11 -DBOOST_THREAD_VERSION=4 -I/usr/local/boost_1_54_0_beta1 -I/usr/include/x86_64-linux-gnu/c++/4.7/32 main.cpp  -pthread -o test -L/usr/local/boost_1_54_0_beta1/stage/lib -lboost_system -lboost_thread

The -m32 is because I build for a 32-bit target on a 64 bit machine. Boost is also compiled with 32-bit.

Regards,
Tobias