请考虑以下类,该类可以处于“非空”或“空”状态,并且在“空”状态下默认初始化其他成员(因此具有不确定的值):
bazel query 'attr(tags, "my-binary", //...:*)'
是否允许从默认构造的struct MaybeInt {
bool has_value;
int value;
MaybeInt() : has_value(false) {}
MaybeInt(int v) : has_value(true ), value(v) {}
};
进行分配,如:
MaybeInt
建筑怎么样?
MaybeInt empty, another;
another = empty; // OK?
如果MaybeInt empty, another(empty); // OK?
的类型为MaybeInt::value
,答案会更改吗?
答案 0 :(得分:2)
another = empty
确实是UB,因为empty.value
有一个indeterminate value,并且因为implicitly defined copy constructor of a class复制了所有成员。
诀窍是将成员value
放在一个联合中。这样implicitly defined copy constructor of the union复制了object representation:
struct MaybeInt {
bool has_value;
union {
int value;
char _dumb;
};
MaybeInt() : has_value(false) {}
MaybeInt(int v) : has_value(true ), value(v) {}
};
NB :这是一个低级技巧,它具有一个可复制的可选内容。这对于提高代码执行速度非常重要。此类可以通过对cpu寄存器的函数调用来传递,而如果不能被普通复制则是不可能的。
答案 1 :(得分:-1)
您的代码导致未定义的行为。
MaybeInt empty, another;
another = empty;
好。 another
具有与empty
相同的未定义值。从技术上讲,会导致实践中的错误。
MaybeInt empty, another(empty);
empty
包含一个未定义的值,并将其复制到具有相同值的another
,只有现在您的类认为才定义它。
使用std::optional, 一切应该是可选的都以标准方式解决。 (C ++ 17)
optional<int> x; // empty or not, you can use `value_or()` to get a default value.