C :包含其属于类的联合
C++: union that contains class it belongs to
虽然编译了此代码而没有任何错误,但我怀疑它是否会按预期工作。这样的筑巢吗?我不能使用Boost和C 17。
class Node;
typedef struct Value {
ValueTag type;
union {
std::int32_t integerValue;
std::float_t floatValue;
bool boolValue;
std::vector<Node> arrayValue;
std::unordered_map<std::string, Node> dictionaryValue;
};
} Value;
class Node {
private:
Value m_value;
public:
virtual ~Node();
};
我怀疑它会按预期工作。
你是正确的。不会。首先,如果您尝试构建Node
,它实际上不会编译。您会得到类似的东西:
prog.cc:26:10: error: call to implicitly-deleted default constructor of 'Node'
Node n;
^
那是因为在union
中,任何非平凡操作都被隐式删除。您必须定义~Value()
才能做正确的事情。假设type
是我们实际上是联合中哪个元素的索引,则可以打开它并调用适当的破坏者。然后做同样的事情以复制和移动。
也就是说,不完整的类型的嵌套也不正常。只要在首次使用前完成,vector
就可以具有不完整的类型。但是unordered_map
没有此津贴。您将必须将值类型包装在其他内容中 - 例如unique_ptr<Node>
或shared_ptr<Node>
。
您在Value
中拥有的是一种具有一百万个不同名称的常见模式:歧视的联合,总和,或者最常见的是variant
。我建议您改用std::variant
(如果您使用的是最近的编译器来支持此类内容)或boost::variant
(否则)(否则)。因此,您有:
using Value = variant<int32_t, float, bool,
std::vector<Node>, std::unordered_map<std::string, Node>>;
这种类型已经可破坏,可复制,可动且可供您访问。
edit 我最初的答案是不正确/误导的,请忽略它。由于原因,请参见下面的评论。CANSES STD ::变体或Boost ::变种反正:)
非平原data(pod)在c- unions中不安全。
尤其是对于此Proplem std ::变体的C 17标准。您可以将Boost ::变体用于C 的早期版本。
问题是,联盟对建筑构造和破坏者一无所知。因此,不可能用联合元素做更多的一般性事情,这是必要的(例如动态内存分配)
- CMake 导入本地共享库以及如何将其包含在标头中
- 即使不包含其标头,如何成功向前声明的类编译?
- 我该如何循环遍历我的数组(缓冲区——包含一个文本文件),并将其打印成30字节的块
- 如何从包含基类指针的容器中调用派生类函数(基于其类型)?
- 如何找到 -lm lib 并将其包含在 CMake 中?
- C++ 如何格式化包含可变整数的文本行,使其在给定宽度内右对齐?
- 打印/修改类对象的特定成员变量,其类定义列表 (STL) 包含的元素类型
- 严重包含在字符串中,除非我将其存储在类C++
- C ,基础课程如何将子类作为成员包含并调用其方法
- 为什么 std::vector 允许对其包含的类型使用可抛出的移动构造函数?
- 为什么要在将 2d 数组传递给函数时将其声明为类型,为什么要在类型中包含行和列
- 尝试在 ahead 文件上使用结构,并将其包含在主文件和类文件中
- Cmake构建一个共享库,其中包含其所有依赖关系
- C :包含其属于类的联合
- 为什么库源文件不包含其标头
- 如何生成包含其所有依赖项的静态库
- 在包含其自身类型的静态成员的类中使用 __declspec(dllimport)
- 无法使用标头保护解决包含其自身的文件(包括标头)的错误
- 如何通过包含其相应的.h文件从.cpp获得函数/类定义
- 使类指针指向包含其成员的地址