
On Tue, Apr 2, 2013 at 7:16 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
I've started to use C++11 lambda functions with Boost.Thread.
The following works with clang-3.2
boost::future<int> f1 = boost::async( []() -> int {return 123;} );
But it fails with gcc-4.6.2, 4.7.2 and 4.8.0
../example/lambda_future.cpp:**25:91: erreur: conversion from ‘boost::future<void>’ to non-scalar type ‘boost::future<int>’ requested boost::future<int> f1 = boost::async( []() -> int {return 123;} );
The current implementation of boost::async uses boost::result_of to get the result type of the callable parameter.
Is this a know bug on boost::result_of or gcc compiler?
I'm seeing exactly the same behaviour in *VS2012 Update 2*. I'm using Boost 1.54.0 beta *r84748* To be more precise: 1) I first was just using boost::future and tried to use the new .then(), here is a full repro: #include <boost/thread/future.hpp> auto ft = boost::async( []{ return 42; } ).then( []( boost::future<int> r ){ return 666; } ); This fails because boost::async() returned a future<void> instead of a future<int>. I suspect the then() call to have the same problem. I can provide the full error log but I think it's not that useful. 2) Just to be sure I tried this full test: #include <boost/thread/future.hpp> int main() { auto ft = boost::async( []{ return 42; } ); // SUCCEED: static_assert( std::is_same< decltype(ft), boost::future<void> >::value, "WTF???" ); // FAILS: static_assert( std::is_same< decltype(ft), boost::future<int> >::value, "Not the expected type!" ); } Both asserts confirm that I don't get what I want. 3) I remembered that there were some issues from usage of boost::result_of in Boost.Log, so to clarify the situation I setup the following full test: #include <boost/utility/result_of.hpp> #include <type_traits> int top() { return 42; } struct K { int operator()(){ return 42; } typedef int value_type; }; auto F = []{ return 42; }; int main() { // A: ALL SUCCEED static_assert( std::is_same< decltype(K()()), int >::value, "Not the expected type!" ); static_assert( std::is_same< decltype(top()), int >::value, "Not the expected type!" ); static_assert( std::is_same< decltype(F()), int >::value, "Not the expected type!" ); // B: ALL SUCCEED static_assert( std::is_same< std::result_of<K()>::type, int >::value, "Not the expected type!" ); static_assert( std::is_same< std::result_of<decltype(top)>::type, int
::value, "Not the expected type!" ); static_assert( std::is_same< std::result_of<decltype(F)()>::type, int ::value, "Not the expected type!" );
// C: ALL SUCCEED std::result_of<K()>::type a = K()(); std::result_of<decltype(top)>::type b = top(); std::result_of<decltype(F)()>::type c = F(); // D: ALL FAILS static_assert( std::is_same< boost::result_of<K()>::type, int >::value, "Not the expected type!" ); static_assert( std::is_same< boost::result_of<decltype(top)>::type, int
::value, "Not the expected type!" ); static_assert( std::is_same< boost::result_of<decltype(F)()>::type, int ::value, "Not the expected type!" ); // E: ALL FAILS boost::result_of<K()>::type d = K()(); // error C2182: 'd' : illegal use of type 'void' boost::result_of<decltype(top)>::type e = top(); // error C2182: 'e' : illegal use of type 'void' boost::result_of<decltype(F)()>::type f = F(); // error C2182: 'f' : illegal use of type 'void'
} This shows clearly that: 1. boost::result_of don't behave like std::result_of on this platform (and from previous discussions, on other platforms too). 2. both std::result_of and decltype() provide the result I expect from reading documentations about these. So far I'm assuming that the problem really is from boost::result_of, but I might be wrong because the differences with std::result_of are not clear to me. ---- Unfortunately this makes future.then() unusable if we expect return types. I don't know if it impacts other libraries (I suspect Boost.Log). Should I report a bug or is it known, already fixed or a misuse? Joel Lamotte