首页 > 解决方案 > 现在是否可以使用当前的 C++ 标准草案版本为具有 const 字段而没有 UB 的类定义复制赋值运算符

问题描述

在 SO 上,我们有很多关于分配给 const 字段和未定义行为 (UB) 的问题。例如,这个接受的答案说,由于 UB,无法为具有 const 字段的类定义复制赋值运算符。

但我检查了 C++ 标准 (N4861) 的当前草案版本。说它将是 UB [basic.life.8]的部分是:

如果在对象的生命周期结束之后,在对象占用的存储空间被重用或释放之前,在原始对象占用的存储位置创建一个新对象,一个指向原始对象的指针,一个指向原始对象的引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,可用于操作新对象,如果:...

原始对象的类型不是 const 限定的,并且,如果是类类型,则不包含任何类型为 const 限定或引用类型的非静态数据成员,并且

现在已替换为:

o1 不是一个完整的 const 对象,并且

我的解释是,下面的代码现在没有 UB。这样对吗?我问这个是因为在示例中,没有 cv 合格成员 - 所以我仍然不清楚。

#include <iostream>

struct C {
  const int i;
  void f() const {
     std::cout << i << "\n";
  }
  C(int i) : i(i) {}
  C& operator=( const C& );
};

C& C::operator=( const C& other) {
  if ( this != &other ) {
    this->~C();                 // lifetime of *this ends
    new (this) C(other);        // new object of type C created
    f();                        // well-defined
  }
  return *this;
}

int main(){
    C c1(1);
    C c2(2);
    c1 = c2;                        // well-defined
    c1.f();
}

事实上,我的观察是它适用于所有主要编译器,但这使它不合法......

标签: c++language-lawyerundefined-behaviorc++20

解决方案


推荐阅读