如何有条件地实例化一个对象?

Tob*_*emi 3 c++ optimization class instantiation conditional-statements

我正在尝试做一些有条件的工作:

Type object;
if (cond) {
    doSomeStuff();
    object = getObject();
    doMoreStuff();
} else {
    doSomeOtherStuff();
    object = getDifferentObject();
    doEvenMoreStuff();
}
use(object);
Run Code Online (Sandbox Code Playgroud)

我能想到解决这个问题的唯一方法是复制use代码(它实际上是我的应用程序中的内联代码)并objectif块的每个分支中声明。如果我想避免重复代码,我必须将它包装在一些 use 函数中,就像上面一样。在实际情况下,此use函数可能需要 5 个以上的参数来基本上继承上下文。这一切看起来很混乱,无法维护。

if (cond) {
    doSomeStuff();
    Type object = getObject();
    doMoreStuff();
    use(object);
} else {
    doSomeOtherStuff();
    Type object = getDifferentObject();
    doEvenMoreStuff();
    use(object);
}
Run Code Online (Sandbox Code Playgroud)

解决这个问题的最佳方法是什么?Type没有默认构造函数,因此片段 1 无法编译。

其他一些语言支持片段 1 - 相关问题:Forcing uninitialised Declaration of member with a default constructor

cig*_*ien 9

您可以使用 IIILE(立即调用初始化 lambda 表达式):

auto object = [&] {
  if (cond) {
    doSomeStuff();
    auto object = getObject();
    doMoreStuff();
    return object;
  } else {
    doSomeOtherStuff();
    auto object = getDifferentObject();
    doEvenMoreStuff();
    return object;
  }
}();  // note that the lambda must be called

use(object);
Run Code Online (Sandbox Code Playgroud)

即使Type不是默认构造的,这也将起作用。

这是一个演示

  • @TobiAkinyemi您可以在所有三个地方编写“Type”而不是“auto”,但这不会改变您获得的副本数量。如果您的编译器不够智能(无法执行 NRVO),这种方法 *可能* 会给您一个额外的移动(而不是复制),否则您将无法移动。在任何一种情况下都不会复制“对象”。 (2认同)

for*_*818 6

把它放在一个函数中:

Type doStuffAndCreateType() {
    doSomeStuff();
    Type object = getObject();
    doMoreStuff();
    return object;
}

Type doOtherStuffAndCreateType() {
    doSomeOtherStuff();
    Type object = getObject();
    doEvenMoreStuff();
    return object;
}

Type object = cond ? doStuffAndCreateType() : doOtherStuffAndCreateType();
use( object );
Run Code Online (Sandbox Code Playgroud)

  • 或者:`类型 object = cond ?doStuffAndCreateType() : doOtherStuffAndCreateType();` 不需要第三个函数。 (3认同)

Rem*_*eau 5

看看std::optional

#include <optional>

std::optional<Type> object;
if (cond) {
    doSomeStuff();
    object = getObject();
    doMoreStuff();
} else {
    doSomeOtherStuff();
    object = getDifferentObject();
    doEvenMoreStuff();
}
use(object.value());
Run Code Online (Sandbox Code Playgroud)

  • @TobiAkinyemi:这不会进行任何堆分配。`std::Optional` 在内部使用新的放置。如果您已经手动进行新的展示位置,那么...就这样做 (2认同)