2015-08-26 33 views
8

Nel mio codice, ho qualcosa di simile:C++ 11: Sta usando std :: move sicuro solo su oggetti temporanei?

unordered_multimap<string, unordered_map<string, string> > mEntities; 
... 
vector<unordered_map<string, string> > rawEntities; 
if (qi::phrase_parse(&buf[0], (&buf[0]) + buf.size(), EntityParser<char*>(), qi::space, rawEntities)) { 
    for (auto &propGroup : rawEntities) { 
     auto search = propGroup.find("classname"); 
     if (search != propGroup.end()) { 
      // is stealing propGroup safe??? 
      mEntities.emplace(search->second, std::move(propGroup)); 
     } 
    } 
} 
// rawEntities goes out of scope here 

Come potete vedere, sto usando std::move su un oggetto di tipo dedotto a unordered_map<string, string>&, che è, ovviamente, non unordered_map<string, string>&&. Tuttavia, so per certo che poiché rawEntities esce dallo scope dopo il ciclo for, i suoi elementi (le string-> string maps) non saranno mai più utilizzati. Quindi sto immaginando che è sicuro rubare (spostare) i suoi dati di elementi perché non saranno più utilizzati.

Quando eseguo il programma, sembra funzionare. Ma questa cattiva pratica/un anti-modello, e in particolare, lo standard garantisce che sia sicuro?

+0

Solo guardando il titolo della domanda, la risposta è che gli oggetti temporanei sono (per definizione) prvalues ​​e 'std :: move' è solo un cast, che in questo caso non è necessario. –

risposta

13

Al contrario. L'utilizzo di std::move su oggetti temporanei è inutile. Sono già valori R e saranno dedotti come riferimenti al valore R quando vengono passati alle funzioni. L'intero punto di std::move consiste nel trasformare i valori L in riferimenti di valore R in modo che possano essere spostati da.

Così sto pensando che è sicuro di rubare (spostare) i suoi elementi di dati perché non intendete usarlo.

Sì, questo è corretto.

3

In generale, gli oggetti temporanei sono senza nome e sono già rvalues ​​. std::move non è realmente applicabile, poiché è senza nome.

Quando è applicabile std::move? Ogni volta che l'oggetto sta per scadere e non sarà più richiesto. Questo è ciò che fa std::move, lancia la categoria di valore in modo tale da poter essere spostata.

È un caso di utilizzo interessante: rubare il contenuto (filtrato) di un contenitore e non solo l'intero contenitore.

Dato il contenuto del vector non stanno per essere richiesto dopo il ciclo for completa, allora sì, che avrebbe funzionato come previsto.