Using std::launder to get a pointer to an active union member from a pointer to an inactive union member?

别说谁变了你拦得住时间么 提交于 2019-12-05 03:57:58

It is explicitly allowed in a note.

basic.life contains the following rule that makes std::launder unnecessary:

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:

  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • neither the original object nor the new object is a potentially-overlapping subobject.

[ Note: If these conditions are not met, a pointer to the new object can be obtained from a pointer that represents the address of its storage by calling std::launder. — end note ]

This "new object is created at the storage location which the original object occupied" case clearly applies here because:

An object is created ... when implicitly changing the active member of a union...

All the bullet conditions are met, as "potentially overlapping subobject" refers to base class subobjects, which union members are not. (And in the version you linked to, that bullet mentioned base class subobjects directly.)

However even if this interpretation were to change against unions, the note specifically mentions that std::launder bypasses this restriction.

Do note that older versions of the Standard excluded subobjects from this rule... but the note makes it clear that std::launder would have bypassed that problem as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!