C 标准:通过复制返回以初始化无RVO的参考:是否有任何副本



让我们考虑下一个示例:

struct big_type {};
// Return by copy
auto factory() { return big_type{}; }
void any_scope_or_function() {
    big_type&& lifetime_extended = factory();
}

在假设下,RVO是禁止或根本不存在的,以任何方式,是否会复制或可以复制big_type()?还是参考将直接绑定到return语句中构建的临时?

我想确定big_type驱动器仅在any_scope_or_function结束时才称为一次。

我使用C 14,以防万一标准版本之间发生某种行为。

假设没有rvo/copy elison,则在

auto factory() { return big_type{}; }

big_type{}将创建一个临时的big_type。然后,此对象将用于复制初始化函数返回的对象。这意味着您在功能中制作的对象将被构造和破坏。

big_type&& lifetime_extended = factory();

RVALUE参考将延长函数返回的寿命,因此我们将总共看到默认的构造函数调用,复制/移动构造函数调用和两个Destructor调用。

现在,如果我们更改

auto factory() { return big_type{}; }

to

big_type factory() { return {}; }

那么我们不再在工厂中创建对象。使用{}直接初始化返回对象

或参考将直接绑定到临时构造的 在返回语句中?

不,不会。这正是(n(rvo是关于/for的,您明确不想要那个。

但是,将尝试的是使用big_type的移动构造函数,从技术上讲,这不是副本。它确实违反了:" big_type destructor仅在 any_scope_or_function结束 时才称为一次,因为它将被称为两次。

gcc/clang具有一个不错的编译器开关:-fno-elide-constructors,可禁用(N(RVO,可用于将来参考。目前,这是一个已打开该选项的测试,显示了双驱动器调用。

最新更新