为什么编译器不允许在 Union 中使用 std::string?
使用 C 时,通常需要使用数据结构可以存储不同类型的数据。一种这样的结构是联合,它将多个变量分配给同一内存位置。然而,出现了一个关于联合对其成员的限制的常见问题。
一个重要的限制是无法在联合中包含具有重要复制构造函数的类。这包括像 std::string 这样的类。要理解原因,请考虑以下场景:
union U { std::string x; std::vector<int> y; }; U u; // <--
传统上,在结构体中,初始化 u.x 或 u.y 会将它们设置为默认值。然而,在联合体中,所有成员共享相同的地址,因此不可能在不覆盖数据的情况下为两个成员分配值。如果两个成员都未初始化,则使用它们将导致未定义的行为。
C 98 通过禁止具有非平凡构造函数的类成为联合成员来解决此问题。具体来说,它在§9.5/1中指出:
“具有非平凡构造函数(12.1)、非平凡复制构造函数(12.8)、非平凡析构函数(12.4)的类的对象,或者非平凡的复制赋值运算符(13.5.3、12.8)不能是联合的成员,此类对象的数组也不能是。”
此限制确保可以处理联合内的数据操作
C 0x 在某种程度上放宽了这一规则(§9.5/2),允许最多一个带有大括号或等号初始化器的非静态数据成员。然而,为联合编写无错误的复制构造函数和析构函数仍然很复杂。因此,标记联合或第三方库(如 boost::variant 和 boost::any)为处理异构数据提供了替代解决方案。
以上是为什么不能在 C 联合中使用 `std::string`?的详细内容。更多信息请关注PHP中文网其他相关文章!