Powiedzmy, że mam dwa wektory i przenoszę jeden do drugiego, v1 = std::move(v2)
; czy po tym stanie jeszcze być w stanie użytecznym?Czy przenoszenie pozostawia obiekt w stanie używalności?
Odpowiedz
Z n3290, 17.6.5.15 przemieszczające się od stanu rodzajów bibliotek [lib.types.movedfrom]
- Przedmioty typów określonych w C++ średnia biblioteki mogą być przemieszczane z (12.8) . Operacje przenoszenia mogą być jawnie określone lub niejawnie wygenerowane. O ile nie określono inaczej, takie przeniesione obiekty należy umieścić w ważnym, lecz nieokreślonym stanie.
Ponieważ stan jest prawidłowy, to znaczy można bezpiecznie operować v2
(na przykład poprzez przypisanie do niego, co byłoby umieścić go z powrotem do znanego stanu). Ponieważ nie jest to określone, oznacza to, że nie można na przykład polegać na żadnej konkretnej wartości dla v2.empty()
, o ile jest w tym stanie (ale wywołanie go nie spowoduje awarii programu).
Należy zauważyć, że ten aksjomat semantyki ruchu ("przeniesiony z obiektów pozostawia się w poprawnym, ale nieokreślonym stanie") jest czymś, do czego cały kod powinien dążyć (przez większość czasu), a nie tylko komponentami biblioteki standardowej. Podobnie jak semantyka konstruktorów kopiowania, powinna ona być kopiowana, ale nie jest wymuszona.
+1, ale sposób w jaki jest napisany, wygląda na to, że nie wiesz, czy 'v2' jest pusty po' v2 = std :: vector {}; ' – Gabriel
@Gabriel Dobra sprawa, edycja jest w porządku. –
Nie, pozostaje w bliżej nieokreślonym stanie.
Fragment open-std-org artykułu -
.. ruch() daje jej docelowa wartość swojego argumentu, ale nie jest zobowiązany do zachowania wartości źródła. Tak więc, dla wektora, move() można rozsądnie oczekiwać, że pozostawi swój argument jako wektor o zerowej wydajności, aby uniknąć konieczności kopiowania wszystkich elementów. Innymi słowy, ruch jest potencjalnie destrukcyjnym odczytem.
Zostaje w nieokreślonym, ale prawidłowym stanie. Oznacza to, że nadal można używać obiektu w sposób, który ma tylko warunek wstępny, że obiekt jest ważny. Na przykład możesz wywołać wektor :: clear() na tym przeniesionym z wektora, aby uzyskać go w znanym stanie, a następnie rozpocząć wstawianie do niego obiektów. – bames53
To __must__ będzie ważne. W przeciwnym razie, co by się stało, gdy obiekt wykracza poza zakres.Najprawdopodobniej nie będzie niczego w swoim magazynie danych, ale cokolwiek to jest, będzie ważne. – Damon
Istnieje wiele (abstrakcyjnych) poziomów ważności. Jeśli chodzi o język, obiekt po przeniesieniu jest ważny, o ile obiekt nadal istnieje, jego destruktor można wywołać bez powodowania niezdefiniowanych zachowań itp. Jednak umowa obiektu może zostać zmieniona z powodu przeniesienia . Na przykład fakt, że wektor stał się wielkością zerową (nie posiadającą pojemności) jest prawidłowym wektorem C++, ale obiektem posiadającym metodę, która ustawia konkretny element na wektorze, bez sprawdzania (teraz unieważnionego) założenia, że wektor powinien mieć określony rozmiar, staje się ... – rwong
Jeśli chcesz używać v2 po przeprowadzce, będziemy chcieli, aby zrobić coś takiego:
v1 = std::move(v2);
v2.clear();
W tym momencie v1 będzie miał oryginalną zawartość v2 i v2 będzie dobrze -definiowany pusty stan. Działa to na wszystkich kontenerach STL (i łańcuchach, jeśli o to chodzi), a jeśli implementujesz własne klasy obsługujące semantykę ruchu, prawdopodobnie będziesz chciał zrobić coś podobnego.
Jeśli twoja konkretna implementacja STL rzeczywiście pozostawia obiekt w stanie pustym, to drugie wyczyszczenie() będzie zasadniczo operacją nieopublikowaną. W rzeczywistości, jeśli tak jest, byłoby prawną optymalizacją dla kompilatora, aby wyeliminować funkcję clear() po ruchu.
- 1. Przejście CSS3 pozostawia ślad
- 2. dlaczego django pozostawia blokady w mysql?
- 3. Dlaczego sed pozostawia wiele plików?
- 4. Dlaczego HttpClient pozostawia gniazda otwarte?
- 5. Uwierzytelnianie Dropbox pozostawia otwarte Przeglądarka
- 6. Czy HHVM będzie w stanie uruchomić PHP7
- 7. JTree zrobić tylko pozostawia przeciągany
- 8. Co się stanie, jeśli obiekt zmieni rozmiar własnego kontenera?
- 9. Przenoszenie pliku w Vim
- 10. Przenoszenie wariancji w R
- 11. Przenoszenie MKCircle w MKMapView
- 12. Co się stanie, jeśli zmieni się obiekt __hash__?
- 13. Czy mogę usunąć zablokowany obiekt?
- 14. Przenoszenie piramidy w Pythonie
- 15. Przenoszenie wiersza w JTable
- 16. Przenoszenie plików w C#
- 17. backbone.js re-rendering pozostawia widoku eventless
- 18. wykryć, czy obiekt jest pusty
- 19. Vim: Przenoszenie kodu
- 20. eksplodować-stanie w PHP
- 21. Jsoup czysty metoda pozostawia elementy
- 22. Czy istnieje sposób przechowywania anonimowego uczestnika w stanie widoku?
- 23. Przenoszenie artykułów blogów w Middleman
- 24. Przenoszenie jednego katalogu w Pythonie
- 25. select() - w stanie timerów
- 26. Przenoszenie elementów w tablicy C#
- 27. w stanie zrozumieć strategiczne wzór
- 28. LinQ odrębny z niestandardowym comparer pozostawia duplikaty
- 29. ZwijanieToolbarLayout czasami pozostawia białe pole poniżej
- 30. Przenoszenie MKOverlayPathView znika za płytkami
To wygląda na duplikat http://stackoverflow.com/q/7027523/576911. Zobacz tę odpowiedź: http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object/7028318#7028318 na to pytanie, które omawia dozwolone operacje pod względem warunków wstępnych. –