如何检查布尔值是否在 C++ 中未初始化?

how to check whether a boolean is uninitialized in c++?

我想为对象的某些(难以计算的)布尔属性创建缓存。我想到的结构如下:

   class Obj; 
   struct ObjProperties
   {
       bool property1;
       bool property2;
       // etc.
   };
   std::unordered_map<const Obj*, ObjectProperties> cache;

现在我想拥有类似

的功能
bool hasProperty1()
{
    if /*(cache[property1] is uninitialized)*/
         cache[property1] = calculateProperty1();
    return cache[propery1];
}

然而我如何检查布尔值是否未初始化? Property1 可以是 true 或 false,所以我无法将它初始化为一个值...

我看到两种处理方法:

1) 使我的结构 bool* 的成员成为指针。然后我可以检查 nullptr,但这使我的函数变得有点麻烦,因为我必须 new/delete 我所有的布尔对象

2) 使我的结构成员成为 int。然后我可以将它们初始化为 -1 并分配 0(假)或 1(真)。但这使我的代码不那么明显。毕竟,这些属性是布尔值,我的缓存结构实际上也包含一些(真实的)整数和双精度数。

处理此问题的最佳方法是什么?还是我忽略了一些非常简单的测试来检查布尔值是否未初始化?

您无法立即知道 POD 类型是否已初始化。编译器分配给变量的内存将有一个值;是否有效,取决于您。

判断变量是否初始化的一种方法是使用 bool 变量。

另一种首选方法是始终在 structclass 或函数的构造函数中初始化它们。

编辑 1:
如果将变量定义为 static,它将在 main 之前初始化(与全局变量一样)或在第一次进入函数时初始化。

对于您的情况,我强烈建议您创建一个 constructor 方法来初始化 struct 中的变量。

您不能强制对内置类型进行初始化,但您可以改用包装器(如果偏执狂,请查询):

/// Initialize a type with zero.
template <typename T>
struct Zero
{
    T value;
    operator const T& () const { return value; }
    operator T& () { return value; }

    Zero()
    :   value(0)
    {}

    Zero(const T& initializer)
    :   value(initializer)
    {}
}; 

struct Some
{
    Zero<bool> property;
};

以上仅确保零(假)初始化。您可以更改模板以支持 true(也),或选择反映 false 状态的名称(大写与 no_uppercase)

拥有 C++11,我更喜欢:

struct Some
{
    bool property = false;
};

如果成员未初始化,则行为不明确。

如果您只有几个属性:

class ObjProperties
{
  bool property1;
  bool property1_valid;
  bool property2;
  bool property2_valid;

  ObjProperties() : property1_valid(false), property2_valid(false)
  {}
}

您可以实现一个特殊的 属性 类型:

struct BoolProperty
{
  bool value;
  bool valid;
  BoolProperty() : value(false), valid(false) {}
  BoolProperty(bool value) : value(value), valid(true) {}
  BoolProperty &operator=(const bool &arg)
  {
     value = arg;
     valid = true;
  }
  bool isValid() const { return valid; }
  ...
}
class ObjProperties
{
  BoolProperty property1;
  BoolProperty property2;
}

或者你可以使用一些位域:

class ObjProperties
{
  bool property1;
  bool property2;
  int property1_valid:1;
  int property2_valid:1;
}