Что такое копирование? Что такое (названная) оптимизация возвращаемого значения? Что они подразумевают?
В каких ситуациях они могут возникнуть? Какие ограничения?
- Если вы получили ссылку на этот вопрос, вы, вероятно, ищете введение .
- Технический обзор см. В стандартной справке .
- Смотрите общие случаи здесь .
c++
optimization
c++-faq
return-value-optimization
copy-elision
Лучиан Григоре
источник
источник
Ответы:
Введение
Для технического обзора - перейдите к этому ответу .
Для распространенных случаев, когда происходит удаление копии - перейдите к этому ответу .
Копирование elision - это оптимизация, реализованная большинством компиляторов для предотвращения лишних (потенциально дорогих) копий в определенных ситуациях. Это делает возврат по значению или передачу по значению осуществимым на практике (применяются ограничения).
Это единственная форма оптимизации, которая исключает (ха!) Правило «как будто» - исключение копирования может применяться, даже если копирование / перемещение объекта имеет побочные эффекты .
Следующий пример взят из Википедии :
В зависимости от компилятора и настроек допустимы следующие выходные данные :
Это также означает, что можно создавать меньше объектов, поэтому вы также не можете полагаться на определенное количество вызываемых деструкторов. У вас не должно быть критической логики внутри конструкторов копирования / перемещения или деструкторов, так как вы не можете полагаться на их вызов.
Если вызов конструктора копирования или перемещения исключен, этот конструктор должен все еще существовать и быть доступным. Это гарантирует, что исключение копирования не позволяет копировать объекты, которые обычно не копируются, например, потому что они имеют закрытый или удаленный конструктор копирования / перемещения.
C ++ 17 : Начиная с C ++ 17, Copy Elision гарантируется, когда объект возвращается напрямую:
источник
Стандартная ссылка
Для менее технического представления и ознакомления - перейдите к этому ответу .
Для распространенных случаев, когда происходит удаление копии - перейдите к этому ответу .
Разрешение на копирование определяется в стандарте в:
12.8 Копирование и перемещение объектов класса [class.copy]
в виде
Пример приведен ниже:
и объяснил:
источник
Распространенные формы исключения
Для технического обзора - перейдите к этому ответу .
Для менее технического представления и ознакомления - перейдите к этому ответу .
(Named) Оптимизация возвращаемого значения является распространенной формой исключения из копирования. Это относится к ситуации, когда объект, возвращаемый значением из метода, получает свою копию. Пример, изложенный в стандарте, иллюстрирует оптимизацию именованного возвращаемого значения , поскольку объект назван.
Регулярная оптимизация возвращаемого значения происходит при возвращении временного:
Другие распространенные места, где исключение копии имеет место, когда временное значение передается по значению :
или когда исключение выдается и перехватывается значением :
Общие ограничения права на копирование:
Большинство компиляторов коммерческого класса поддерживают функцию копирования elision & (N) RVO (в зависимости от настроек оптимизации).
источник
Copy elision - это метод оптимизации компилятора, который исключает ненужное копирование / перемещение объектов.
В следующих обстоятельствах компилятору разрешено пропускать операции копирования / перемещения и, следовательно, не вызывать связанный конструктор:
Даже если исключение копии имеет место и конструктор копирования / перемещения не вызывается, он должен присутствовать и быть доступным (как если бы оптимизация вообще не происходила), в противном случае программа некорректна.
Вы должны разрешить такое копирование только в тех местах, где это не повлияет на наблюдаемое поведение вашего программного обеспечения. Исключение копирования является единственной формой оптимизации, которой разрешено иметь (т.е. исключать) наблюдаемые побочные эффекты. Пример:
GCC предоставляет
-fno-elide-constructors
возможность отключить копирование elision. Если вы хотите избежать возможного копирования, используйте-fno-elide-constructors
.Теперь почти все компиляторы предоставляют разрешение на копирование, когда оптимизация включена (и если никакая другая опция не установлена для ее отключения).
Вывод
При каждом исключении копии одна конструкция и одно соответствующее уничтожение копии опускаются, что экономит время ЦП, а один объект не создается, тем самым экономя место на фрейме стека.
источник
ABC obj2(xyz123());
это НРВО или РВО? разве он не получает временную переменную / объект такой же какABC xyz = "Stack Overflow";//RVO