Ecco una possibile definizione di std::swap
:Su attuazione std :: scambio in termini di assegnazione di movimento e spostare costruttore
template<class T>
void swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Credo che
std::swap(v,v)
è garantito per avere alcun effetto estd::swap
può essere implementato come sopra.
La seguente citazione mi sembra implicare che queste convinzioni siano contraddittorie.
17.6.4.9 Argomenti delle funzioni [res.on.arguments]
1 Ciascuno dei seguenti si applica a tutti gli argomenti a funzioni definite nella libreria standard C++, se non diversamente specificato.
...
- Se un argomento funzione si lega ad un parametro di riferimento rvalue, l'applicazione può supporre che questo parametro è un riferimento unico per questo argomento. [Nota: se il parametro è un parametro generico del modulo & & e un lvalue di tipo A è associato, l'argomento si lega a un riferimento di lv lvalue (14.8.2.1) e pertanto non è coperto dalla precedente frase . - nota finale] [Nota: se un programma esegue un lvalue su un valore durante il passaggio di tale valore a una funzione di libreria (ad esempio tramite chiamando la funzione con l'argomento move (x)), il programma è chiedendo effettivamente tale funzione a tratta quel lvalue come temporaneo. L'implementazione è gratuita per ottimizzare i controlli di aliasing che potrebbero essere necessari se l'argomento era un lvalue. -endnote]
(grazie a Howard Hinnant per providing the quote)
Lasciate v
essere un oggetto di un certo tipo mobile tratto dalla Standard Template Library e considerano la chiamata std::swap(v, v)
. Nella riga a = std::move(b);
sopra, è il caso all'interno di T::operator=(T&& t)
quello this == &b
, quindi il parametro è non un riferimento univoco. Si tratta di una violazione del requisito sopra riportato, pertanto la riga a = std::move(b)
richiama il comportamento non definito quando viene chiamato da std::swap(v, v)
.
Qual è la spiegazione qui?
* Qual è la spiegazione? * Cos'è che deve essere spiegata? –
@ DavidRodríguez-dribeas Ho assunto due cose e sono arrivato ad una contraddizione - 'std :: move (v, v)' è garantito per non fare nulla e inoltre è un comportamento indefinito. Queste due affermazioni non possono essere entrambe corrette. Quindi qualcosa non va nel mio ragionamento o nelle ipotesi. Qual è la cosa sbagliata? –
Intendi 'std :: swap (v, v)', non 'std :: move (v, v)', giusto? –