Копирующая инициализация
class A {
int _x;
public:
A(int x) : _x(x) {}
};
int main()
{
A s = 2; // вот она
}
Я не понимаю как это работает? Так как копирующая инициализация инициализирует объект из другого объекта, компилятор видит литерал int и приводит к типу A, то есть в теории должен вызваться конструктор для создания анонимного объекта, что бы потом вызвать конструктор копирования и инициализировать объект s анонимным объектом? Получается что это будет выглядеть так: A s = A(2);?
На практике компилятор это все оптимизирует будет вызван один конструктор. Получается если ход мыслей верный, то по этой причине копирующая инициализация носит такое название?
Ответы (1 шт):
должен вызваться конструктор для создания анонимного объекта, что бы потом вызвать конструктор копирования
До С++17 так и происходит. И непонятно, почему стандарт не требует вызывать сразу правильный конструктор, без копирования.
Но:
- Тут перемещение, а не копирование.
- Не
A s = A(2);, аA s(A(2));. Это проверяется деланием перемещающего (или копирующего, если перемещающего нет) конструктораexplicit. - Любой нормальный компилятор соптимизирует перемещение. От него остается только требование наличия перемещающего (или копирующего) конструктора, но и это требование исчезает в С++17.
- Начиная С++17, все это неважно, потому что компилятор обязан выбросить перемещение, не проверяя наличие перемещающего (или копирующего) конструктора. Поэтому
A s = 2;превращается просто вA s(2);, с единственной разницей, что конструктор от int-а не может бытьexplicit.