Questa domanda riguarda le specifiche di diverse funzioni nella libreria standard C++ 11, che prendono i loro argomenti come riferimenti di valore, ma non consumali in tutti i casi. Un esempio è std::unordered_set<T>::insert(T&&)
.std :: unordered_set <T> :: insert (T &&): è un argomento spostato se esiste
È abbastanza chiaro che questo metodo utilizzerà il costruttore di spostamenti di T
per costruire l'elemento all'interno del contenitore, se non esiste già. Tuttavia, cosa succede se l'elemento esiste già nel contenitore? Sono abbastanza sicuro che non vi sia alcun motivo per cambiare l'oggetto nel caso. Tuttavia, non ho trovato nulla nello standard C++ 11 che supporta il mio reclamo.
Ecco un esempio per mostrare perché questo potrebbe essere interessante. Il seguente codice legge le righe da std :: cin e rimuove la prima occorrenza delle righe duplicate.
std::unordered_set<std::string> seen;
std::string line;
while (getline(std::cin, line)) {
bool inserted = seen.insert(std::move(line)).second;
if (!inserted) {
/* Is it safe to use line here, i.e. can I assume that the
* insert operation hasn't changed the string object, because
* the string already exists, so there is no need to consume it. */
std::cout << line << '\n';
}
}
Apparentemente, questo esempio funziona con GCC 4.7. Ma non sono sicuro, se è corretto secondo lo standard.
Sarebbe inefficiente muoversi quando non è richiesto, ma solo lo standard è importante. Buona domanda! –
'std :: cout << line << '\ n';' Nota che lo standard non dice che questo funzionerà. 'line' sarà lasciato in uno" stato valido con un valore non specificato. " Dovresti invece controllare 'line.empty()'. –
Tutto ciò sembra fare un ottimo rapporto sui difetti. –