Chociaż aktualne odpowiedzi są w zasadzie poprawne, to jest niezdefiniowane zachowanie, ponieważ używasz nieokreślonej wartości, szczegóły są nieco bardziej zaangażowane. W przypadku typów pierwotnych uważam, że albo Does initialization entail lvalue-to-rvalue conversion? Is int x = x; UB? lub Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++1y? zapewniają wystarczającą szczegółowość, aby zrozumieć, dlaczego zachowanie jest niezdefiniowane.
Dla typu zdefiniowanego przez użytkownika nie wydaje mi się, aby zawierał on wystarczająco dużo szczegółów. Widzimy z tego dość stary, ale istotne defect report 63: Initialization of class from self który pyta:
And if so, what is the semantics of the self-initialization of UDT?
i stanowi przykład, w którym jedynie odniesienie i adres jest podjętą klasy w trakcie budowy, a odpowiedź mówi:
3.8 basic.life paragraph 6 indicates that the references here are valid. It's permitted to take the address of a class object before it is fully initialized, and it's permitted to pass it as an argument to a reference parameter as long as the reference can bind directly.
Odwołuje się do sekcji 3.8
Czas życia obiektu, ponieważ obiekt jest w trakcie budowy, a jego pamięć została przydzielona, ale jego żywotność nie rozpoczęła się, ponieważ jego inicjalizacja nie została zakończona.
Jeśli spojrzymy w pkt 6
z sekcji 3.8
mówi (podkr):
Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a glvalue refers to allocated storage (3.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:
i obejmuje:
the glvalue is used to access a non-static data member or call a non-static member function of the object,
Więc zanim zakończeniu inicjowania nie możemy podjąć wartość niestatycznego elementu danych, który wyraźnie będzie wymagany podczas kopiowania konstrukcji urządzenia std::string
.
Przynajmniej twój kod jest okropny. Nigdy nie należy tak kodować, ponieważ jest nieczytelne (dla ludzi). –
1. Nie 2. Nie. Inicjujesz ciąg znaków z jego (niezainicjowanym) ja. – juanchopanza
Tak więc błąd jest bardziej prawdopodobny w VS2013, jeśli taki istnieje. Ale twój kod jest błędny. –