Пространства имён
Варианты
Действия

copy elision

Материал из cppreference.com
< cpp‎ | language

 
 
Язык С++
Общие темы
Управление программой
Операторы условного выполнения
Операторы повторения
Операторы перехода
Функции
объявление функции
объявление лямбда-функции
шаблон функции
спецификатор inline
спецификаторы исключений (устарело)
спецификатор noexcept (C++11)
Исключения
Пространства имён
объявление пространства имён
псевдонимы пространства имён
Типы
спецификатор decltype (C++11)
Спецификаторы
cv-спецификаторы
спецификаторы продолжительности хранения
спецификатор constexpr (C++11)
спецификатор auto (C++11)
спецификатор alignas (C++11)
Инициализация
Литералы
Выражения
Утилиты
Типы
typedef-объявление
объявление псевдонима типа (C++11)
атрибуты (C++11)
Приведения типов
неявные преобразования
const_cast-преобразование
static_cast-преобразование
dynamic_cast-преобразование
reinterpret_cast-преобразование
C-подобное и функциональное приведение типов
Выделение памяти
Классы
Особые свойства классовых функций
Специальные функции-члены
Шаблоны
шаблон класса
шаблон функции
специализация шаблона
упакованные параметры (C++11)
Разное
Ассемблерные вставки
 
Оптимизирует из копирования и перемещения-конструкторов, в результате нуль-копии проходят по значению семантики.
Оригинал:
Optimizes out copy- and move-constructors, resulting in zero-copy pass-by-value semantics.
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

Содержание

[править] Объяснение

При следующих обстоятельствах, составители разрешается опускать копирования и перемещения-конструкторов класса объектов, даже если копировать / перемещать конструктор и деструктор иметь наблюдаемые побочные эффекты.
Оригинал:
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.
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • Если функция возвращает тип класса по значению, и выражение return заявление является имя энергонезависимой объект с автоматическим срок хранения, который не является функцией параметра или параметров вылов положение, и которая имеет такой же 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".
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • Когда безымянный временное, не привязаны к какой-либо ссылки, будут перемещены или скопированы в объект того же CV-неквалифицированный тип копирования / перемещения опускается. Когда это временное построен, он построен прямо в хранилище, где она в противном случае будут перемещены или скопированы. Когда безымянных временных является аргументом оператора возврата, этот вариант копии элизии известен как РВО ", возвращается значение оптимизации".
    Оригинал:
    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".
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • В вбрасывания выражение, если операндом является имя энергонезависимой объект с автоматическим срок хранения, который не является функцией параметра или параметров вылов пункта, и, масштабы которых не выходит за внутренний попробуйте-блок ( если есть попытка блока), то копирования / перемещения опускается. Когда это локальная переменная построена, она построена непосредственно в хранилище, в котором объект исключения, в противном случае будут перемещены или скопированы. (начиная с 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)
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • При обращении исключение, если аргумент улова пункте того же типа (за исключением резюме квалификации) в качестве объекта исключения бросили, копирования / перемещения опущена, а тело улова пункте доступ к объекту исключения непосредственно, как если он был передан по ссылке. (начиная с 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)
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Несколько elisions копия может быть прикован к устранению нескольких копий.
Оригинал:
Multiple copy elisions may be chained to eliminate multiple copies.
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Notes

Копировать элизии это разрешено только форма оптимизации, которые могут изменить наблюдаемые побочные эффекты. Поскольку некоторые компиляторы не выполняют копии элизии в любой ситуации, где это разрешено, программы, которые полагаются на побочные эффекты копирования / перемещения конструкторы и деструкторы не переносимы.
Оригинал:
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.
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Даже тогда, когда копия элизии имеет место и 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.
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Пример

#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()
}

Возможный вывод:

constructed
constructed
constructed
constructed
constructed
constructed
arg.size() = 3
destructed
destructed
destructed
destructed
destructed
destructed

[править] См. также