是否允许从具有一些不确定值的对象分配?

时间:2019-07-02 18:34:17

标签: c++ initialization

请考虑以下类,该类可以处于“非空”或“空”状态,并且在“空”状态下默认初始化其他成员(因此具有不确定的值):

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,答案会更改吗?

2 个答案:

答案 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.