单独构造结构的数据成员是否合法?

Is it legal to construct data members of a struct separately?

class A;
class B;
//we have void *p pointing to enough free memory initially
std::pair<A,B> *pp=static_cast<std::pair<A,B> *>(p);
new (&pp->first) A(/*...*/);
new (&pp->second) B(/*...*/);

上面的代码执行后,*pp是否保证处于有效状态?我知道我测试过的每个编译器的答案都是正确的,但问题是根据标准这是否合法,因此是否合法。此外,如果 AB 在 C++98/03 中不可移动,是否还有其他方法可以获得这样的 pair? (感谢@StoryTeller-UnslanderMonica,自 C++11 以来,std::pair 有一个分段构造函数)

“访问”不存在的 pair 对象的成员是每个 [basic.life]/5 未定义的行为; pair 永远不是 POD-class (具有用户声明的构造函数),因此指向其存储空间的指针可能不会用于其成员。目前尚不清楚形成指向成员的指针是否已经未定义,或者 new 是否已定义。

在 C++98 中也没有办法构造一对不可复制(当然不是 可移动)类型——这就是添加分段构造函数的原因 连同移动语义。

一个更简单的问题:使用定义明确的文字字符串吗?

甚至没有,因为它的生命周期没有定义。您不能在符合规范的代码中使用字符串文字。

因此,从未花时间明确定义字符串文字的委员会显然没有费心指定 哪些 类型的 class 对象可以通过以下方式存在placement new 其子对象 - 显然不能以这种方式创建多态对象!

该标准甚至没有费心描述联合的语义。

关于生命周期的标准无处不在,这不仅仅是社论:它反映了认真的人之间对生命周期的开始、对象是什么、左值是什么等的深刻分歧。

值得注意的是,人们有各种错误或矛盾的直觉:

  • 一次调用 malloc
  • 无法创建无限数量的对象
  • 一个左值引用一个对象
  • 重叠对象违反对象模型
  • 未命名对象只能由 new 或编译器创建(临时对象) ...