C++ std::promise可以从非POD对象生成吗?

C++ std::promise可以从非POD对象生成吗?,c++,asynchronous,promise,C++,Asynchronous,Promise,我的应用程序所做的一件事就是监听和接收来自套接字的有效负载。我从不想阻止。在接收到的每个有效负载上,我想创建一个对象并将其传递给工作线程,直到稍后再考虑它,这就是原型代码的工作方式。但是对于生产代码,我希望通过使用方便的异步方法来降低复杂性(我的应用程序很大)。async从承诺中获得未来。为此,我需要在下面由Xxx类表示的非POD对象上创建一个承诺。我看不到任何方法可以做到这一点(请参阅下面我的示例代码中的错误)。在这里使用异步是否合适?如果是这样,我如何构造一个比int更复杂的promise/

我的应用程序所做的一件事就是监听和接收来自套接字的有效负载。我从不想阻止。在接收到的每个有效负载上,我想创建一个对象并将其传递给工作线程,直到稍后再考虑它,这就是原型代码的工作方式。但是对于生产代码,我希望通过使用方便的异步方法来降低复杂性(我的应用程序很大)。async从承诺中获得未来。为此,我需要在下面由Xxx类表示的非POD对象上创建一个承诺。我看不到任何方法可以做到这一点(请参阅下面我的示例代码中的错误)。在这里使用异步是否合适?如果是这样,我如何构造一个比int更复杂的promise/future对象(我看到的所有代码示例都使用int或void):

#包括
类Xxx//非POD对象
{
int i;
公众:
Xxx(inti):i(i){}
int GetSquare(){return i*i;}
};
整数阶乘(标准::未来f)
{
int res=1;
自动xxx=f.get();
对于(int i=xxx.GetSquare();i>1;i--)
{
res*=i;
}
返回res;
}
int _tmain(int argc,_TCHAR*argv[]
{
Xxx Xxx(2);//2表示来自套接字的一个有效负载
std::promisep;//错误:没有合适的默认构造函数可用
std::futuref=p.get_future();
std::futurefu=std::async(阶乘,std::move(f));
p、 设置_值(xxx);
等等;
返回0;
}

听起来您的实现有缺陷。应该不需要默认构造函数(根据[utility.arg.requirements]的常规库要求),GCC接受您的代码(将奇怪的Microsoftish
\u tmain更改为标准的
main


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

< P>正如迈克已经回答的,它绝对是VisualC++实现的一个错误: STD::承诺< /C>,你所做的应该工作。< /P> 但我很好奇你为什么要这么做。也许您还没有展示一些其他要求来保持示例的简单性,但这将是编写代码的明显方式:

#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();
}
#包括
类Xxx//非POD对象
{
int i;
公众:
Xxx(inti):i(i){}
int GetSquare(){return i*i;}
};
整数阶乘(Xxx)
{
int res=1;
对于(int i=xxx.GetSquare();i>1;i--)
{
res*=i;
}
返回res;
}
int main()
{
Xxx Xxx(2);//2表示来自套接字的一个有效负载
std::futurefu=std::async(阶乘,std::move(xxx));
int-fact=fu.get();
}

您是否尝试过给
Xxx
一个默认的ctor?为什么不将
Xxx
传递给异步函数呢?你真的需要未来的双向沟通吗?这意味着两个线程都在等待对方。我明白了。因为我已经有了有效载荷数据,所以没有必要对它做出承诺/未来。只需使用asnyc的_Fty&&u Fnarg、_ArgTypes&&_带复杂参数的Args构造函数。对。您可以使用
future
async
中获取结果,但不需要使用它来传递任何信息。是的,实现中肯定存在缺陷<当调用
set\u value
时,code>promise
应创建未初始化的缓冲区,并仅构造
Xxx
对象。另一个解决办法是使用<代码> Boo::承诺< /C> >而不是<代码> STD<代码> ONEI是一个C++ MFC HugER。我跳过了java和C++技术的解析器,很高兴能使用这些新的ISO标准化能力以及我所有其他C++库(GUI,加密等)。事实上,根据Herb Sutter在2014年构建时的说法,是MS将其异步实现提交给了标准社区以供纳入。我假设[utility.arg.requirements]声明您应该能够在承诺中传递任何类型的arg?[utility.arg.requirements]不是特定于
promise
的,它只是说“一般来说,不需要默认构造函数。”是auto xxx=f.get();还是有必要的,因为我以后不会再路过这里了?哦,很好。我忘了换那个位子了,现在修好了。这确实是个错误。我已经提交了一份报告。这个bug甚至被列为文件中的todo项(“//todo:_Associated_state ctor假设_Ty是默认可构造的”),因此开发人员已经很清楚了。
#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();
}