Идентична ли инициализация копирования инициализации копирования копии?

#c #initialization #copy-elision #copy-initialization

#c #инициализация #копирование-устранение #копирование-инициализация

Вопрос:

В следующих двух сегментах кода представлена задача инициализации переменной b как копии a . Первый сегмент кода инициализирует переменную с помощью инициализации копирования (инициализация с использованием = ). Предположим, что класс Apple просто определен как пустой класс: class Apple {};

 Apple a;
Apple b = a;
 

Второй сегмент кода инициализирует переменную, также используя инициализацию копирования. Хотя то, что копируется при инициализации, является копией a .

 Apple a;
Apple b = Apple(a);
 

При чтении этого вслепую кажется, что копирование происходит at Apple(a) , а другое at Apple b = ... . В противоречии, переопределение конструктора копирования Apple для печати чего-либо в копии показывает, что во время выполняется только одна копия Apple b = Apple(a) .

Являются ли эти два оператора Apple b = a; и Apple b = Apple(a); идентичными? Существуют ли случаи, когда они не идентичны?

Ответ №1:

Да, по идее Apple b = Apple(a); , сначала создается временное Apple a , а затем b инициализируется копирование из временного. Из-за исключения копирования, поскольку эффект b инициализируется a напрямую.

При следующих обстоятельствах компиляторы должны опустить копирование и переместить построение объектов класса, даже если конструктор копирования / перемещения и деструктор имеют наблюдаемые побочные эффекты. Объекты создаются непосредственно в хранилище, куда они в противном случае были бы скопированы / перемещены. Конструкторы копирования / перемещения не обязательно должны присутствовать или быть доступными:

  • При инициализации объекта, когда выражение инициализатора является значением prvalue того же типа класса (игнорируя cv-квалификацию), что и тип переменной:

Этот вид исключения копирования гарантирован начиная с C 17, до C 17 это оптимизация. При компиляции в режиме до C 17 и с опцией, запрещающей оптимизацию, вы можете увидеть разницу между двумя случаями.

ЖИВЫЕ КОНЦЕРТЫ

Комментарии:

1. Была ли эта оптимизация до C 17 реализована независимо разработчиками компилятора? Или, была ли официальная документация, в которой говорилось, что разработчики компилятора должны рассмотреть возможность реализации этой оптимизации?

2. @TarasPalczynski Стандарт не требует такой оптимизации до C 17, он просто допускает такую оптимизацию. Хотя большинство компиляторов, которые я знаю, поддерживают это.

3. Есть ли какой-либо ресурс, который указывает в списке, какие компиляторы поддерживают эту оптимизацию до C 17? Или единственный реалистичный способ — просто попробовать каждый компилятор и посмотреть, что он делает?

4. @TarasPalczynski Боюсь, я этого не знаю… Возможно, вам потребуется проверить документ компиляторов или протестировать код.