价值回报是否意味着额外的拷贝和额外的开销?C++
Does return-by-value mean extra copies and extra overhead? C++
考虑以下内容:
class Foo { ... };
Foo rbv();
void caller()
{
Foo x = rbv(); ← the return-value of rbv() goes into x
...
}
Foo rbv()
{
...
return Foo(42, 73); ← suppose Foo has a ctor Foo::Foo(int a, int b)
}
将构造多少个Foo类型的对象?
也许吧。
在C++11中,如果值有move构造函数,则通过移动而不是复制来返回值。这可能比复制效率高得多。
在某些情况下,例如返回局部变量或临时变量时(如您在此处所做的),移动或复制可以被删除。该值直接创建到调用方的堆栈帧中,因此在返回时不需要移动或复制它。喜欢缩写词的人有时会称之为(N)RVO-(命名)回报值优化。
同样,也可以消除从临时返回值到x
的复制或移动。
任何合适的编译器都会实现这种优化,因此您的代码应该只创建一个Foo
。您可以通过使析构函数打印一条消息来验证这一点,并注意到它只执行一次:http://ideone.com/xydJqY.如果禁用优化,则最多可能有三个对象。
最多可以有两个副本:一个从临时Foo(42, 73)
到函数的返回值,另一个从函数的返回到x
。但是,这两个副本都有资格进行副本省略,这允许不进行复制,而是直接在目标中构建对象,相当于Foo x(42, 73);
。
您可能能够控制编译器利用副本省略的程度;例如,在GCC中,您可以使用-fno-elide-constructors
来获取所有两个副本。
相关文章:
- 实现无开销push_back的最佳方法是什么
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- 类型擦除的std::function与虚拟函数调用的开销
- 一组值的零开销下标运算符
- C++ 特征库:引用的性能开销<>
- C++对开销较少的容器使用多个过滤器
- 在编译时评估函数开销的通用方法
- 在循环中调用同一虚函数的开销
- 使用静态成员函数而不是普通函数是否有任何开销?
- 自定义运算符重载C++,无开销
- 在 v8 JavaScript 中重复调用C++是否有巨大的开销?
- 将 mmap 内存用于开销非常低的循环缓冲区
- 与纯 V8 相比,NodeJS 是否有任何性能缺陷或显著开销?
- 非 constexpr 变量模板的开销是否为零?
- 右值引用是否具有与右值引用相同的开销?
- 实例成员与静态成员与非类方法的开销
- 如果使用lambda,std::unique_ptr如何没有大小开销
- 放置新[]的开销
- 这种获取模板参数包中最后一个元素的方法是否有隐藏的开销?