copy elision
来自cppreference.com
该页由英文版wiki使用Google Translate机器翻译而来。
该翻译可能存在错误或用词不当。鼠标停留在文本上可以看到原版本。你可以帮助我们修正错误或改进翻译。参见说明请点击这里. |
优化复制和移动的构造函数,在按值传递的零拷贝语义.
原文:
Optimizes out copy- and move-constructors, resulting in zero-copy pass-by-value semantics.
目录 |
[编辑] 解释
在下列情况下,编译器允许省略的复制和移动,复制/移动的构造函数和析构函数的类对象的构造函数,即使已经观察到的副作用.
原文:
Under the following circumstances, the compilers are permitted to omit the copy- and move-constructors of class objects even if copy/move constructor and the destructor have observable side-effects.
- 如果一个函数返回一个类类型的值,return语句的表达是自动存储时间,这是不是函数的参数,或catch子句参数,并具有相同的CV非易失性对象的名称不合格类型的函数的返回类型,然后复制/移动省略。当该局部变量的构造,它是直接在构造函数的返回值被移动或复制到存储。这种变异被称为NRVO的副本省略“命名返回值优化”原文:If a function returns a class type by value, and the return statement's expression is the name of a non-volatile object with automatic storage duration, which isn't the function parameter, or a catch clause parameter, and which has the same cv-unqualified type as the return type of the function, then copy/move is omitted. When that local variable is constructed, it is constructed directly in the storage where the function's return value would otherwise be moved or copied to. This variant of copy elision is known as NRVO, "named return value optimization".
- 当一个无名暂时的,未绑定到任何引用,将移动或复制到相同的CV无保留意见类型的对象,复制/移动的被省略了。当该临时构成,它直接构造如否则将被移动或复制到存储在存储。当无名的临时复制省略的说法,一个return语句,这种变异被称为RVO,“返回值优化”原文:When a nameless temporary, not bound to any references, would be moved or copied into an object of the same cv-unqualified type, the copy/move is omitted. When that temporary is constructed, it is constructed directly in the storage where it would otherwise be moved or copied to. When the nameless temporary is the argument of a return statement, this variant of copy elision is known as RVO, "return value optimization".
- 在罚球表现,如果操作数是自动存储时间,这是不是函数的参数,或catch子句参数,并且其范围并没有扩大过去最内层的try块非易失性对象的名称(如果有一个try块),然后复制/移动被省略。当该局部变量的构造,它直接构造的异常对象被移动或复制到存储。 (C++11 起)原文:In a throw-expression, if the operand is the name of a non-volatile object with automatic storage duration, which isn't the function parameter, or a catch clause parameter, and whose scope does not extend past the innermost try-block (if there is a try-block), then copy/move is omitted. When that local variable is constructed, it is constructed directly in the storage where the exception object would otherwise be moved or copied to. (C++11 起)
- 当处理异常,如果该参数的catch子句抛出的异常对象是相同的类型(CV资格的除外),复制/移动的被忽略和身体直接访问异常对象的catch子句,作为如果它是通过引用传递。 (C++11 起)原文:When handling an exception, if the argument of the catch clause is of the same type (except for cv-qualification) as the exception object thrown, the copy/move is omitted and the body of the catch clause accesses the exception object directly, as if it was passed by reference. (C++11 起)
多个的副本elisions可能是链接,以消除多个副本.
原文:
Multiple copy elisions may be chained to eliminate multiple copies.
[编辑] 注释
,复制elision是唯一允许的优化,可以改变观察到的副作用。因为有些编译器不执行复制省略,它允许在任何情况下,依赖于复制/移动的构造函数和析构函数的副作用是不可移植的。
原文:
Copy elision is the only allowed form of optimization that can change the observable side-effects. Because some compilers do not perform copy elision in every situation where it is allowed, programs that rely on the side-effects of copy/move constructors and destructors are not portable.
即使在副本省略发生copy-/move-constructor,不叫,它必须存在且可访问,否则程序是病态的形成。
原文:
Even when copy elision takes place and the copy-/move-constructor is not called, it must be present and accessible, otherwise the program is ill-formed.
[编辑] 示例
#include <vector> #include <iostream> struct Noisy { Noisy() {std::cout << "constructed\n"; } Noisy(const Noisy&) { std::cout << "copied\n"; } Noisy(Noisy&&) { std::cout << "moved\n"; } ~Noisy() {std::cout << "destructed\n"; } }; std::vector<Noisy> f() { std::vector<Noisy> v = std::vector<Noisy>(3); // copy elision from temporary to v return v; // NRVO from v to the nameless temporary that is returned } void fn_by_val(std::vector<Noisy> arg) { std::cout << "arg.size() = " << arg.size() << '\n'; } int main() { std::vector<Noisy> v = f(); // copy elision from returned temporary to v fn_by_val(f()); // and from temporary to the argument of fn_by_val() }
Possible output:
constructed constructed constructed constructed constructed constructed arg.size() = 3 destructed destructed destructed destructed destructed destructed