可以从非POD对象创建std :: promise吗?

时间:2015-03-11 16:07:56

标签: c++ asynchronous promise

我的应用程序所做的一件事就是从套接字中侦听和接收有效负载。我永远不想阻止。在收到的每个有效负载上,我想创建一个对象并将其传递给工作线程并忘记它,直到稍后原型代码如何工作。但是对于生产代码,我希望通过使用方便的异步方法来降低复杂性(我的应用程序很大)。 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;
}

2 个答案:

答案 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之后)

我切换到不同的编译器和操作系统。这对你来说可能不是一个选择,所以也许你可以给这个类一个默认的构造函数来保持它的快乐。