我的应用程序所做的一件事就是从套接字中侦听和接收有效负载。我永远不想阻止。在收到的每个有效负载上,我想创建一个对象并将其传递给工作线程并忘记它,直到稍后原型代码如何工作。但是对于生产代码,我希望通过使用方便的异步方法来降低复杂性(我的应用程序很大)。 async采用了承诺的未来。为了实现这一点,我需要在Xxx类下面表示的非POD对象上创建一个promise。我没有看到任何方法(请参阅下面的示例代码中的错误)。在这里使用异步是否合适?如果是这样,我如何构造一个比int更复杂的promise / future对象(我看到的所有代码示例都使用int或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;
}
答案 0 :(得分:5)
正如迈克已经回答的那样,它肯定是std::promise
的Visual C ++实现中的一个错误,你正在做的事情应该有效。
但我很好奇为什么你还需要这样做。也许还有一些其他要求,你没有表现出让这个例子变得简单,但这是编写代码的明显方法:
#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();
}
答案 1 :(得分:3)
听起来你的实施有缺陷。应该不需要默认构造函数(根据[utility.arg.requirements]的一般库要求),GCC接受您的代码(在将奇怪的Microsoft _tmain
更改为标准main
之后)
我切换到不同的编译器和操作系统。这对你来说可能不是一个选择,所以也许你可以给这个类一个默认的构造函数来保持它的快乐。