One of the things my app does is listen for and receive payloads from a socket. I never want to block. On each payload received, I want to create an object and pass it to a worker thread and forget about it until later which is how the prototype code works. But for the production code I want to reduce complexity (my app is large) by using the convenient async method. async takes a future made from a promise. For that to work I need to create a promise on my non-POD object represented below by the Xxx class. I don't see any way to do that (see error in my sample code below). Is it appropriate to use async here? If so, how can I construct a promise/future object that is more complex than int (all code examples I've see either use int or void):
#include <future>
class Xxx //non-POD object
{
int i;
public:
Xxx( int i ) : i( i ) {}
int GetSquare() { return i * i; }
};
int factorial( std::future< Xxx > f )
{
int res = 1;
auto xxx = f.get();
for( int i = xxx.GetSquare(); i > 1; i-- )
{
res *= i;
}
return res;
}
int _tmain( int argc, _TCHAR* argv[] )
{
Xxx xxx( 2 ); // 2 represents one payload from the socket
std::promise< Xxx > p; // error: no appropriate default constructor available
std::future< Xxx > f = p.get_future();
std::future< int > fu = std::async( factorial, std::move( f ) );
p.set_value( xxx );
fu.wait();
return 0;
}
As Mike already answered, it's definitely a bug in the Visual C++ implementation of std::promise
, what you're doing should work.
But I'm curious why you need to do it anyway. Maybe there's some other requirement that you've not shown to keep the example simple, but this would be the obvious way to write that code:
#include <future>
class Xxx //non-POD object
{
int i;
public:
Xxx( int i ) : i( i ) {}
int GetSquare() { return i * i; }
};
int factorial( Xxx xxx )
{
int res = 1;
for( int i = xxx.GetSquare(); i > 1; i-- )
{
res *= i;
}
return res;
}
int main()
{
Xxx xxx( 2 ); // 2 represents one payload from the socket
std::future< int > fu = std::async( factorial, std::move( xxx ) );
int fact = fu.get();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With