2012-10-29 17 views
32

Che cosa dice lo standard C++ 11 sull'assegnazione del movimento autonomo in relazione alla libreria standard? Per essere più concreti, cosa, se non altro, è garantito su cosa fa selfAssign?Che cosa garantisce la libreria standard sull'assegnazione del movimento autonomo?

template<class T> 
std::vector<T> selfAssign(std::vector<T> v) { 
    v = std::move(v); 
    return v; 
} 
+4

@ Mark Non penso che questo sia un duplicato. Questa domanda riguarda la scrittura personale. Questa domanda riguarda ciò che garantisce la libreria standard. –

+2

Nota che questo * non * implica l'assegnazione auto-spostamento di 'T'. – Xeo

+0

@Xeo Ho rimosso quella linea. Grazie per aver segnalato l'errore. –

risposta

31

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 invalutato. -endnote]

Così, l'attuazione di std::vector<T, A>::operator=(vector&& other) è consentito di supporre che other è un prvalue. E se other è un valore nominale, l'assegnazione automatica non è possibile.

cosa è probabile che accada:

v sarà lasciato in uno stato (0 capacità) risorsa-less. Se v ha già 0 capacità, questo sarà un no-op.

Aggiorna

Il latest working draft, N4618 è stato modificato per indicare chiaramente che nei requisiti MoveAssignable l'espressione:

t = rv 

(dove rv è un rvalue), t deve essere solo il valore equivalente di rv prima dell'assegnazione se t e rv non fanno riferimento allo stesso oggetto. E a prescindere, lo stato di rv non è specificato dopo l'assegnazione.C'è una nota aggiuntiva per ulteriori chiarimenti:

rv deve ancora soddisfare i requisiti del componente libreria che lo sta utilizzando, anche se non t e rv si riferiscono allo stesso oggetto.

+4

Se capisco correttamente la tua citazione, la funzione 'selfAssign' richiama il comportamento indefinito perché le precondizioni dell'operatore di assegnazione del movimento non sono soddisfatte. La mia comprensione è che 'std :: swap' eseguirà l'assegnazione della propria mossa sulla chiamata' std :: swap (v, v) '. Questo lo rende un comportamento indefinito per chiamare 'std :: swap (v, v)'? –

+0

Interessante. Ciò significherebbe che '&&' implica '__restrict' per gli argomenti allora; Mi chiedo se qualche compilatore ne approfitta ancora. –

+1

@MatthieuM .: Questo è solo ciò che dice lo standard sulle * proprie funzioni *; questa non è una dichiarazione generale sui parametri '&&'. Non saresti limitato a quello nel codice che scrivi. –

0

Non succederà nulla. Un operatore di assegnazione intelligente potrebbe restituire immediatamente se &other == this. Altrimenti assegnerà i suoi interni a se stessi, non facendo nulla.

+0

Sì, ma qui i membri del rvalue sono gli stessi. Stai cercando di dire che alla fine, tutto è perduto? –

+0

No, oggi faccio un pessimo lavoro di lettura di domande. Mie scuse. –

+0

Speriamo che questo risponda meglio alla tua domanda. –

Problemi correlati