- Może być ważny (1). Aby rozwiązać konkretny problem związany z życiem dtor/ctor, tak, to jest ważne (2). Tak działała oryginalna implementacja wektora.
- To może być dobry pomysł (prawdopodobnie nie jest), ale może nie chcieć kanoniczny sposób. (3)
(1) Nie ma kontrowersji, czy ruchy muszą być ważne w skrzynia z automatycznym ruchem. Argumenty przemawiające za bezpieczeństwem na własny ruch to pozycja, w której kod powinien być bezpieczny (duh), z pewnością oczekujemy, że samo przypisanie będzie bezpieczne. Również niektóre raporty z doświadczeń użytkowników, że dla wielu algorytmów, które używają ruchu, samodzielne przenoszenie jest możliwe i żmudne do sprawdzenia.
Argumenty przemawiające za bezpieczeństwem samodzielnego przemieszczania się to pozycja, w której semantyka całego punktu ruchu to oszczędność czasu i dlatego ruchy powinny być tak szybkie, jak to tylko możliwe. Samokontrola może być kosztowna w stosunku do kosztu przeniesienia. Zauważ, że kompilator nigdy nie wygeneruje kodu z automatycznym przeniesieniem, ponieważ naturalne wartości r (nie są rzutowane) nie mogą zostać przesunięte samodzielnie. Jedynym sposobem na samodzielne poruszanie się jest, gdy rzutowanie "std :: move()" jest jawnie wywoływane. Powoduje to obciążenie wywoływacza std :: move() w celu sprawdzenia, czy samo-ruch nie jest zaangażowany, lub przekonania się, że tak nie jest. Zauważ także, że byłoby trywialnie utworzyć zdefiniowany przez użytkownika odpowiednik "std :: move", który sprawdzałby dla self-move, a następnie nie zrobił nic. Jeśli nie popierasz samosiężenia, możesz to udokumentować.
(2) To nie jest szablon, dzięki czemu można się dowiedzieć, czy wyrażenie "new (this) Class (std :: move (rhs))" może rzucić. Jeśli może, to nie, to nie jest poprawne.
(3) Ten kod może być zagadką dla opiekunów, którzy mogą spodziewać się bardziej tradycyjne podejście wymiany, ale istnieje potencjalne wady podejścia swap. Jeśli zasoby wyzwalane przez cel muszą zostać zwolnione jak najszybciej (takie jak muteks), to zamiana ma tę wadę, że zasoby są zamieniane na obiekt źródłowy ruchu. Jeśli ruch jest wynikiem wywołania "std :: move()", obiekt źródłowy ruchu może nie zostać natychmiast usunięty. (Ponieważ nie jest to szablon, możesz wiedzieć, jakie zasoby są zwalniane.) Jeśli pamięć jest jedynym zasobem, który jest zwalniany, nie stanowi to problemu.)
Lepszym rozwiązaniem może być uwzględnienie uwolnienia zasobów kod z destruktora i kod przenoszący zasoby z konstruktora ruchu, a następnie po prostu wywołaj te (inline) procedury w tym operatorze przypisania ruchu.
Co się stanie, jeśli '~ Class' lub' new (this) Class (std :: move (rhs)) wyrzuci? – Yakk