auto a = A(3);
oznacza to samo, co A a = A(3);
, ponieważ typem prawej strony jest A
.
Oznacza to dokładnie jak to wygląda: A(3)
tworzy tymczasowy A
zainicjowany z 3
, a następnie A a = _____
oznacza: stworzyć A
nazywa a
z _____
jako inicjatora.
Tworzysz tymczasowy plik, przekazujesz go jako a
jako inicjator, a następnie tymczasowy plik zostaje zniszczony. Ten rodzaj inicjowania (z =
) nazywa się inicjowanie kopii (chociaż nie mylić tego z "kopią", to tylko słowo).
Konstruktor jest wybrany do konstrukcji a
, która akceptuje A
. Musi to być konstruktor copy lub move. A
ma konstruktor ruchu i konstruktor kopiowania. Ten ostatni jest generowany domyślnie i definiowany jako usunięty, ponieważ istnieje konstruktor ruchu deklarowany przez użytkownika.
Definicja jako usunięta nie wpływa jednak na rozdzielczość przeciążania; a konstruktor ruchu jest w tym przypadku preferowany względem konstruktora kopiowania.
Twój kod próbuje wywołać funkcję d, która jest źle sformułowana, stąd błąd.
Należy zauważyć, że jeśli konstruktor ruchu nie został usunięty, to zastosowanie miałaby kopia elision. Występuje w niektórych okolicznościach, gdy zmienna jest inicjowana z tymczasowego lub zmienna lokalna jest zwracana przez wartość. Zasadą jest, że kompilator może używać tej samej pamięci zarówno dla obiektu a
, jak i obiektu tymczasowego, i ominąć wywołanie konstruktora kopiowania/przenoszenia.
Większość/wszystkie kompilatory robią to w takiej sytuacji. Możesz więc napisać auto a = A(3);
iw praktyce nie dostaniesz niepotrzebnych ruchów. Jeśli napiszesz kod dla twojego konstruktora ruchu, który coś wypisze, będziesz miał nadzieję, że nic nie jest wyprowadzane.
Jeśli chcesz mieć absolutną pewność, że nie ma niepotrzebnej kopii lub skonstruować obiektu, który nie ma użytecznych kopii ani przenieść konstruktora - przestań pisać kod, który określa niepotrzebne kopie! A a(3);
jest wystarczająca.
Odnośnie pierwszego komentarza, mam wrażenie, że jest to często przedstawiane jako "są one takie same, z wyjątkiem kwestii technicznych, które zazwyczaj nie pojawiają się". Ale może wkładam słowa w usta OP. – Hurkyl
Ktokolwiek wprowadza je jako taki, powinien zostać zwolniony z powodu niekompetencji. – Blindy
Dlaczego kompilator generuje inny kod, gdy intencja jest wyraźnie taka sama? Czy istnieje przypadek, w którym programista będzie chciał tego zachowania? – Shmoopy