Tu jest możliwe określenie std::swap
:Na realizację std :: swapa pod względem przypisania ruchu i poruszać konstruktora
template<class T>
void swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
wierzę, że
std::swap(v,v)
gwarantuje nie mają skutków istd::swap
można zaimplementować jak wyżej.
Poniższy cytat wydaje mi się sugerować, że te przekonania są sprzeczne.
17.6.4.9 Argumenty funkcji [res.on.arguments]
1 Każdy z poniższych odnosi się do wszystkich argumentów do funkcji zdefiniowanych w C++ biblioteki standardowej, o ile wyraźnie nie zaznaczono inaczej.
...
- Jeśli argumentem funkcji wiąże się z parametrem odniesienia rvalue, implementacja może zakładać, że parametr ten jest unikalnym odniesienie do ten argument. [Uwaga: Jeśli parametr jest parametrem generycznym postaci T & & i l wartość typu A jest powiązany, argument jest powiązany z wartością odniesienia o wartości l (14.8.2.1) i dlatego nie jest objęty poprzednim zdaniem . - nota końcowa] [Uwaga: Jeśli program rzuci wartość l do wartości o wartości , przekazując tę lwartośc do funkcji bibliotecznej (np. Przez wywołanie funkcji z argumentem move (x)), program jest skutecznie prosząc tę funkcję do traktuj tę lwartość jako tymczasową. Implementacja jest bezpłatna, aby zoptymalizować kontrole aliasingu z zewnątrz, które mogą być potrzebne, jeśli argument był l-wartości. -endnote]
(dzięki Howard Hinnant dla providing the quote)
Niech v
być przedmiotem pewnego rodzaju ruchomego pobranej od Standard Template Library i rozważyć połączenie std::swap(v, v)
. W powyższej linii a = std::move(b);
jest to przypadek wewnątrz T::operator=(T&& t)
, który jest , więc parametr to , a nie unikalne odniesienie. Jest to naruszenie powyższego wymogu, więc linia a = std::move(b)
wywołuje niezdefiniowane zachowanie po wywołaniu z std::swap(v, v)
.
Jakie jest wyjaśnienie tutaj?
* Jakie jest wytłumaczenie? * Czego wymaga wyjaśnienie? –
@ DavidRodríguez-dribeas Przyjąłem dwie rzeczy i doszedłem do sprzeczności - 'std :: move (v, v)' gwarantuje, że nic nie robi, a także nieokreślone zachowanie. Te dwa stwierdzenia nie mogą mieć obu racji. Coś jest nie tak z moim rozumowaniem lub z założeniami. Które coś jest nie tak? –
Masz na myśli 'std :: swap (v, v)', a nie 'std :: move (v, v)', prawda? –