[英]Placement-new an STL container and destroying it safely afterwards
This code implements an unrestricted union which provides access by name and by index to any of its three members. 此代码实现了一个不受限制的联合,该联合通过名称和索引提供对其三个成员中任何一个的访问。
Since std::string
is non-trivially constructed and destroyed, I need to provide special constructor and destructor for the union
. 由于
std::string
是非平凡的构造和销毁的,因此我需要为union
提供特殊的构造函数和析构函数。
#include <iostream>
#include <string>
using namespace std ;
union MyUnion{
string parts[3] ;
struct{ string part1, part2, part3 ; } ;
MyUnion(){
new(parts+0) string ; //constructs the 3 strings in-place
new(parts+1) string ;
new(parts+2) string ;
}
~MyUnion(){
parts[0].~string() ; //calls string's destructor
parts[1].~string() ;
parts[2].~string() ;
}
} ;
int main(){
MyUnion u ;
u.part1 = "one" ; //access by name
u.part2 = "two" ;
u.part3 = "three" ;
cout << u.parts[0] << endl ; //access by index
cout << u.parts[1] << endl ;
cout << u.parts[2] << endl ;
}
This example compiles and works fine (seemingly), but my questions are: 此示例可以编译并正常运行(貌似),但是我的问题是:
string
's constructor throws an exception? string
的构造函数抛出异常怎么办? Does that need to be caught so as to not try to destroy an object that was never constructed? The code compiles in VC2015, which does support unnamed structs. 该代码在VC2015中编译,它确实支持未命名的结构。 Please disregard that detail.
请忽略该细节。
Is it safe to do this?
这样安全吗?
No. First, the common initial sequence rule only allows reading of members, not writing: 不会。首先,通用的初始序列规则仅允许读取成员,而不能写入:
In a standard-layout union with an active member (9.3) of struct type
T1
, it is permitted to read a non-static data memberm
of another union member of struct typeT2
providedm
is part of the common initial sequence ofT1
andT2
;在具有结构类型
T1
的活动成员(9.3)的标准布局联合中,允许读取结构类型T2
的另一个联合成员的非静态数据成员m
,条件是m
是T1
的公共初始序列的一部分,并且T2
; the behavior is as if the corresponding member ofT1
were nominated.行为就像提名了
T1
的相应成员一样。
Secondly, common initial sequence is a trait of standard layout types: 其次,常见的初始序列是标准布局类型的特征:
The common initial sequence of two standard-layout struct (Clause 9) types is [...]
两种标准布局结构(第9条)的常见初始序列为[...]
and std::string
is not required to be standard-layout. 并且
std::string
不需要是标准布局。
Is it safe to do this?
这样安全吗?
It depends on what you are willing to call safe. 这取决于您愿意称之为安全的东西。 The code certainly invokes undefined behaviour by any reasonable interpretation of the standard.
该代码肯定会通过对该标准的任何合理解释来调用未定义的行为。
You cannot read an inactive member of a union, except when there's a common subsequence involved (9.3 Unions), but these union members have no common initial sequence because the notion is only defined for two standard-layout structs (9.2 Class Members/20) and one member of the union is not a struct at all. 您不能读取联盟的非活动成员,除非涉及一个公共子序列(9.3个联盟),但是这些联盟成员没有共同的初始序列,因为该概念仅针对两个标准布局结构定义(9.2类成员/ 20)工会的一个成员根本不是一个结构。 It's an array so it cannot have a common initial sequence with anything.
它是一个数组,因此不能有任何共同的初始序列。
This also applies to analogous code that uses primitive types, eg int x[3];
这也适用于使用原始类型的类似代码,例如
int x[3];
and struct {int x0, x1, x2};
和
struct {int x0, x1, x2};
. 。 There's not even a guarantee that
x2
and x[2]
have the same address. 甚至不能保证
x2
和x[2]
具有相同的地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.