让我们考虑下一个示例:
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,可用于将来参考。目前,这是一个已打开该选项的测试,显示了双驱动器调用。