【问题标题】:How to Empty-Initialize a `const` Member如何清空初始化一个`const`成员
【发布时间】:2018-03-11 20:34:55
【问题描述】:

我有一种情况,我有一个const 成员变量,但在某些控制路径中我可以保证我不会访问它。在这些情况下,当我构造对象时,我不想浪费时间初始化该成员。


考虑以下玩具示例:

struct Foo {
    int val;
    Foo() {}
};
auto function() { return Foo(); }

这会产生所需的程序集(Clang 5.0.0 -O3):

function():                           # @function()
        ret

但是,如果我按照我的意愿将int val; 更改为int const val;,编译将失败(因为必须初始化const 成员):

struct Foo {
    int const val;
    Foo() {} //<- Fails!  `const` members must be initialized.
};

如何初始化int const val;,但又不增加任何运行时成本?例如,我应该如何修复上例中的标记线?


注意:默认初始化 val(即使用 Foo() : val() {} 或 Foo() = default;)是不可接受的,因为这会将 val 初始化为零:

function():                           # @function()
        xor     eax, eax
        ret

【问题讨论】:

  • 您真的处于无法接受xor eax, eax 的情况吗?如果是这样,那具体是什么情况?
  • 在一个可怜的、糟糕的int的情况下,需要使用世界上最精确的原子钟来测量未初始化上述@987654337的增益(如果有的话) @。只需将其初始化为零,然后继续处理更紧迫的问题。对于更昂贵的对象,std::optional 将是可能的解决方案。
  • @NeilButterworth 正如我所写,这是一个玩具示例。 IRL,val 可能是一个实际的对象,在这种情况下开销可以任意大。

标签: c++ oop constructor initialization constants


【解决方案1】:

你应该首先问这是否可能,如果是,如何。

在这种情况下,答案是否,因为类的 const 数据成员必须由您或默认初始化值初始化。


PS:这必须是过早优化的经典案例,因为初始化变量在时间方面相对便宜。

【讨论】:

    【解决方案2】:

    如果它只是一个 int,你就不能真正节省时间。 如果它更复杂,请使用std::optional&lt;T&gt;。初始化它非常便宜(如果为空,则单个位设置为 0),您可以查询它是否已初始化,它只是内存中的一位开销,并且在运行时为零(如果已知为非空,则取消引用没有if 在合理的优化实现中)。

    extern bool ShouldInit;
    
    struct Foo {
        std::optional<MyExpensiveType> oMyStuff_;
        Foo()
            : oMyStuff(ShouldInit ? make_optional<MyExpensiveType>()
                                  : std::nullopt) {}
        int fn()
        {
            return oMyStuff_ ? *oMyStuff_
                               : 0;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      • 2014-09-08
      • 2015-04-27
      • 2013-01-07
      • 2011-04-01
      相关资源
      最近更新 更多