首页 > 解决方案 > 我可以在构造函数的主体中转发构造吗?

问题描述

让我们考虑在一个类的构造函数执行期间S,似乎S可以使用另一个构造函数来构造。一种解决方案可能是创建一个新的位置this以重用存储:

struct S{
    unsigned int j; //no const neither reference non static members
    S(unsigned int i){/*...*/}
    S(int i){
       if (i>=0) {
         new (this) S(static_cast<unsigned int>(i));
         return;}
       /*...*/
       }
    };
 int i=10;
 S x{i};//is it UB?

存储重用在[basic.life]中定义。在构造函数执行期间(重新)使用存储时,我不知道如何阅读本节。

标签: c++constructorlanguage-lawyer

解决方案


在这种情况下,该标准完全没有指定,我找不到相关的 CWG 问题。

就其本身而言,您的新展示位置不是 UB。毕竟你有没有对象的存储,所以你可以直接在里面构造一个对象。正如你所说的,第一个对象的生命周期还没有开始。

但现在的问题是:原始对象会发生什么?因为通常情况下,构造函数只在没有对象的存储上调用,构造函数的结束标志着对象生命周期的开始。但是现在已经有另一个对象了。新对象是否被销毁?它没有效果吗?

该标准在 [class.cdtor] 中缺少一个段落,该段落说明如果在正在构造和销毁的对象的存储中创建新对象会发生什么。

你甚至可以构建更奇怪的代码:

struct X {
  X *object;
  int var;
  X() : object(new (this) X(4)), var(5) {} // ?!?
  X(int x) : var(x) {}
} x;

推荐阅读