I am getting unexpected results from boost::async()
(Boost 1.56, Windows: VS2010 and VS2012).
#include <boost/thread/future.hpp>
...
auto func = [](){ return 123; };
auto boostFut = boost::async(func);
// boostFut = 42; // intentional error to reveal deduced type in compilation error
For some reason boostFut
is deduced as boost::unique_future<void>
instead of boost::unique_future<int>
.
What am I doing wrong?
Note: on VS2012, if I used std::async(func)
instead of boost::async(func)
it does work as expected and the future type is deduced as int
.
boost::async
needs to determine the resultant type of the argument functor's call. In order to do that, Boost uses its own boost::result_of<T>
class template implementation. That is, async
declaration looks as below:
template <class F>
boost::future<typename boost::result_of<typename boost::decay<F>::type()>::type>
async(F f);
Depending on the compiler's capabilities/boost's configuration, boost::result_of<T>
trait may work in one of the two ways:
decltype()
from the call expression.result_type
typedef within F
or a nested result<T>
class template within F
(if a number of the functor's arguments is greater than zero, as overloads may exist).If the latter approach (2) is used, neither of the aforementioned alternatives are applicable for lambda's type, therefore Boost ends up with default assumption deducing void
as a return type.
To make sure your Boost implementation will use decltype()
operator (that works for lambda's call expressions fine), you need to prepend a define prior to Boost headers inclusion:
#define BOOST_RESULT_OF_USE_DECLTYPE
or add this define to boost/config/user.hpp
file.