Почему мой конструктор копирования вызывается только дважды в этом сценарии?

У меня есть следующие две функции:

Class foo(Class arg)
{
return arg;
}

Class bar(Class *arg)
{
return *arg;
}

Теперь, когда я вызываю только foo (arg), конструктор копирования, конечно, вызывается дважды. Когда я звоню в бар (&arg) только он вызывается только один раз. Таким образом, я бы ожидал

foo(bar(&arg));

конструктор копирования вызывается здесь три раза. Однако, это все еще только вызвано дважды. Это почему? Компилятор распознает, что другая копия не нужна?

Заранее спасибо!

6

Решение

Компилятор распознает, что другая копия не нужна?

Это действительно так. Компилятор выполняет копирование / перемещение. Это единственное исключение из так называемого правила «как если бы», и оно позволяет компилятору (при некоторых обстоятельствах, например, как в вашем примере) исключать обращения к конструктору копирования или перемещения класса, даже если они имеют сторону последствия.

В соответствии с пунктом 12.8 / 31 стандарта C ++ 11:

При соблюдении определенных критериев реализация может опустить конструкцию копирования / перемещения класса.
объект, даже если выбран конструктор для операции копирования / перемещения и / или деструктор для объекта
имеют побочные эффекты
. В таких случаях реализация обрабатывает источник и цель пропущенного копирования / перемещения.
операция, как просто два разных способа обращения к одному и тому же объекту, и уничтожение этого объекта
происходит в более поздние времена, когда два объекта были бы уничтожены без оптимизации.
Это исключение операций копирования / перемещения, называемых копия elision, допускается при следующих обстоятельствах (которые
могут быть объединены для устранения нескольких копий):

— в return оператор в функции с типом возвращаемого класса, когда выражение является именем
энергонезависимый автоматический объект (отличный от параметра функции или оператора catch) с тем же cv-unqualified
type в качестве типа возврата функции, операция копирования / перемещения может быть опущена путем конструирования
автоматический объект непосредственно в возвращаемое значение функции

— […]

— когда будет скопирован / перемещен временный объект класса, который не был связан со ссылкой (12.2)
для объекта класса с таким же cv-неквалифицированным типом, операция копирования / перемещения может быть опущена
построение временного объекта непосредственно в цель пропущенного копирования / перемещения

— […]

С GCC вы можете попробовать использовать -fno-elide-constructor флаг компиляции, чтобы подавить эту оптимизацию и посмотреть, как будет вести себя компилятор, когда не происходит исключения копирования.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]