2009-03-20 2 views
6

В previous question оказалось, что простая функция возвращаемого значения всегда копирует свой аргумент return в назначаемую переменную.Оптимизация конструктора копий по сравнению с оптимизацией возвращаемого значения

Требуется ли это по стандарту, или можно оптимизировать функцию, построив переменную «назначено» даже внутри тела функции?

struct C { int i; double d; }; 

C f(int i, int d) { 
    return C(i,d); // construct _and_ copy-construct? 
} 

int main() { 
    C c = f(1, 2); 
} 

ответ

7

Стандарт позволяет любому уровень копирования бездействия здесь:

  • построить локальную временный, копирование построить его в качестве возвращаемого значения, а затем скопировать построить возвращаемое значение в локальный «с». OR
  • Создайте локальную временную копию и скопируйте ее в "c". ИЛИ
  • конструкт «с» с аргументами «I, D»
+0

Не могли бы вы предоставить номер раздела из стандарта, пожалуйста? –

+0

То же, что и Нейл: 12.15. Вы интерпретируете это по-другому? – 2009-03-20 12:11:30

7

Стандарт говорит, что конструктор копирования не нужно использовать - смотрите раздел 12.8/15:

15 Всякий раз, когда объект временного класса копируется с помощью конструктора копирования, и этот объект и копия имеет тот же самый cv-неквалифицированный тип, реализация разрешается обрабатывать оригинал и копию в виде двух различных способов обращения к того же объекта, а не выполнить копию на все, даже если класс copy конструктор или деструктор имеют сторону эффекты.

И многое другое в подобном ключе.

+0

12.5 в моем стандарте 1998 года «Свободный магазин» вы ссылаетесь на какой-то еще стандарт? –

+0

Должно быть 12,8/15 – 2009-03-20 12:13:40

-1

Там один очень простой и хороший способ, чтобы избежать подобных соображений полностью - вы можете рассмотреть возможность возвращения повышающий :: shared_ptr для создаваемого объекта - это будет практически то же самое, когда дело касается юзабилити, но ваш объект, безусловно, не будет скопирован без необходимости - и это будет верно, если вы вернете его, хотя несколько уровней вызовов функций.

+0

это не хорошо для shared_ptr std :: string или std :: pair или std :: vector. –

+0

Чтобы избежать копирования, я мог бы использовать кучу i.s.o. хранения стека. Я знаю это:)/ Но я хотел знать, могу ли я доверять компилятору, то есть стандарту _guarantee_, вызывающему мой конструктор копирования. Который я не могу. – xtofl

+0

Любопытно: зачем вам эта гарантия в любом случае xtof? – 2009-03-20 12:13:52

0

Путь не передавать параметр по ссылке и присваивать ему результат?

+0

, потому что он более уродливый и менее гибкий на сайте вызова. это должно быть сделано только в критичных по производительности местах. – 2009-03-20 12:45:01

+0

Или когда вам нужно несколько возвращаемых значений (статус и значение, например) – xtofl