在C ++中交换未初始化的成员是否安全?

时间:2017-08-05 14:08:52

标签: c++

我正在处理哈希表,并且我有一个包含我的键值的存储桶类型,所以我可以将它们保存在联合中并保持未初始化以避免为它们要求DefaultConstructible:

template <class K, class V>
struct bucket {
     bucket() : hash(SENTINEL) {}
     bucket(uint64_t hash, K&& k, V&& v) 
       : hash(hash), key(std::forward(k)), val(std::forward(v)) {}

     <copy constructors>

    ~bucket() { 
         if (hash != SENTINEL) {
             key.~K();
             val.~V();
         }
      }

     uint64_t hash;
     union { K key; }
     union { V key; }
};

那么,我的问题就像是=运算符,我通常会用复制和交换习语写出来:

bucket& operator =(bucket other) {
     using std::swap;
     swap(hash, other,hash);
     swap(key,  other.key);
     swap(val,  other.val);
}

这是否仍然安全,即使使用了单位化的键和val?

1 个答案:

答案 0 :(得分:5)

这甚至更早失败:读取除最后一个成员之外的union成员是UB。

如果您尚未为任何会员分配值,您也无法阅读任何会员,无论其类型或任何&#34;阅读未经注册的变量&#34;规则。

正如我在评论中提到的,避免默认可构造要求的正确方法是使用新的位置。