Вы должны написать поддерживаемый код, в большинстве случаев компиляторы действительно способны делать правильные вещи для повышения производительности.Если вы чувствуете, что дела идут медленно, то измерьте производительность, и после того, как вы нашли узкое место, попытайтесь выяснить, как его улучшить.
Вы правы в том, логически код запускаетразличные конструкции копирования: от custom_img
до возвращенного временного объекта и затем до объекта img
в коде вызывающей стороны, но факт заключается в том, что обе копии будут исключены.
В частном случае возврат по значению против конструкция по умолчанию + передача по ссылке , все соглашения о вызовах, которые я знаю о реализации , возвращают по значению , если вызывающая сторона выделяет память и передаетскрытый указатель на вызываемого, который эффективно реализует то, что вы пытаетесь сделать.Таким образом, с точки зрения производительности, они в основном эквивалентны.
Я писал об этом (семантика значений в аргументах функций и возвращаемых значениях) в прошлом в этих двух записях блога:
РЕДАКТИРОВАТЬ : я намеренно избегал обсужденияслучаи, когда NRVO не может быть применен компилятором, причина в том, что любая функция f
, которая может принимать ссылку на объект для обработки: void f( T & out ) { /* code */ }
, может быть тривиально преобразована в функцию, где NRVO тривиально для компилятора, чтобы реализовать этовозвращает значение путем простого преобразования в: T f() { T out; /* code */ return out; }