Как называется эта оптимизация компилятора C ++ (вызывая собственный конструктор объектов для своего экземпляра), и как он работает? - PullRequest
2 голосов
/ 02 февраля 2020

Я пытаюсь узнать об управлении ресурсами в C ++, и в моих исследованиях я столкнулся с интересной оптимизацией. По сути, при инициализации объекта в стеке с помощью конструктора копирования, где этот объект является объектом rvalue (это rvalue?), Вместо вызова конструктора и последующего вызова конструктора перемещения, компилятор просто вызывает конструктор исходного объекта.

Object c(Object(1)); // This is the same as Object c(1);
Object c(Object(Object(Object(Object(Object(1)))))); // This is also the same as Object c(1);
Expected flow:
1. Object(1) calls the constructor and creates a nameless Object that will be removed as soon as it's created.
2. c notices this is an rvalue, and calls the move constructor.
3. Destructor for Object(1) is called.
Actual flow:
1. c(1) is called.

Это умно, но .. Как? Какой механизм стоит за этим трюком? Это работает, даже если конструктор для Object принимает указатели и множество аргументов.

1 Ответ

5 голосов
/ 02 февраля 2020

До C ++ 17 это поведение подпадает под copy elision . Object(x) указывает на создание временного объекта, но компилятор может по своему усмотрению исключить создание и уничтожение всех временных объектов в некотором сценарии ios.

Начиная с C ++ 17 это изменилось , теперь Object(x) означает, что рано или поздно может быть Object, созданный с помощью инициализатора x. Этот объект называется объект результата , и идентичность объекта результата определяется контекстом, в котором это выражение появляется, в вашем коде c является объектом результата для всех выражений этой формы, и обе строки в точности идентичны Object c(1);. Это относится ко всем выражениям категории prvalue .

Последнее обеспечивает большую уверенность кодеров в том, что ненужные копии не будут сделаны.

...