This question already has answers here:
Why compiler doesn't allow std::string inside union?
(7个答案)
5年前关闭。
我有一个看起来像这样的工会:
编译时,出现以下错误消息(是的,我做了
我使用以下命令进行编译:
如何在联合中使用
(7个答案)
5年前关闭。
我有一个看起来像这样的工会:
union {
int intValue;
double doubleValue;
std::string stringValue;
void *pointerValue;
} values;
编译时,出现以下错误消息(是的,我做了
#include <string>
):./Value.hh:19:19: error: union member 'stringValue' has a non-trivial copy constructor
std::string stringValue;
^
/Developer/SDKs/MacOSX10.7.sdk//usr/include/c++/4.2.1/bits/basic_string.h:434:7: note: because
type 'std::basic_string<char>' has a user-declared copy constructor
basic_string(const basic_string& __str);
^
我使用以下命令进行编译:
$ clang++ *.cc -isysroot /Developer/SDKs/MacOSX10.7.sdk/ -shared
如何在联合中使用
std::string
? 最佳答案
你不能。
联合结合了两个功能:存储对象的能力(可能是多种类型的对象),以及在这些类型之间有效(和实现定义的)转换的能力。您可以输入一个整数,然后将其表示为 double 。依此类推。
因为联合必须同时支持这两项功能(以及出于其他一些原因,例如能够构造一个),所以联合会阻止您执行某些操作。即,您不能在其中放置“ Activity ”对象。任何“生存”到需要非默认副本构造函数(包括许多其他限制)的对象都不能成为联合的成员。
毕竟,并集对象实际上并不具有实际存储哪种数据类型的概念。它不存储一种类型的数据。它同时存储所有这些。取决于您是否可以选择正确的类型。那么,如何合理地将一个工会值(value)复制到另一个工会值(value)呢?
工会的成员必须是POD(普通旧数据)类型。尽管C++ 11确实放宽了这些规则,但对象仍然必须具有默认(或其他琐碎的)复制构造函数。而且std::string
的副本构造函数并不简单。
您可能想要的是 boost::variant
。这是一个可以存储许多可能类型的对象,就像联合一样。但是,与联合不同,它是类型安全的。因此,它知道工会中实际上是什么。因此,它能够复制自身,并表现得像普通的C++对象。
关于c++ - union 成员具有一个非平凡的拷贝构造函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7299171/