2013-11-21 9 views
5

Ho cercato ma ho trovato solo domande sul costruttore di movimenti con il valore mappato , ma voglio provare qualcosa di diverso.Spostamento di tasti da unordered_map

È possibile utilizzare std::move la chiave da un std::unordered_map? La ragione è piuttosto semplice: mi piacerebbe costruire un esempio in cui creo un vettore dalla mappa, sprecando il meno possibile di memoria. So che rovinerebbe la rappresentazione della mappa, ma hey, dopotutto non userò mai più la mappa, quindi avrebbe senso spostare i valori.

La mia ipotesi è questa: no, non posso farlo. Tuttavia, vorrei una conferma.

Ecco un semplice codice. Mi aspettavo di vedere il costruttore del movimento chiamato, ma ho chiamato il costruttore della copia.

Cheers & Grazie!

#include <iostream> 
#include <unordered_map> 
#include <vector> 
#include <string> 
#include <utility> 

class prop 
{ 
public: 
    prop(const std::string &s, int i) : s_(s), i_(i) { std::cout << "COPIED" << std::endl; }; 

    prop(std::string &&s, int i) : s_(std::move(s)), i_(i) { std::cout << "MOVED" << std::endl; }; 

    std::string s_; 
    int   i_; 
}; 

std::string gen_random(const int len) { 
    static const char alphanum[] = 
    "ABC"; 

    std::string s; 
    s.resize(len); 

    for (int i = 0; i < len; ++i) { 
     s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; 
    } 

    return s; 
} 

int main() 
{ 
    const long n = 3, len = 4, max = 20; 

    std::unordered_map<std::string, int> map; 

    std::cout << ">>GENERATING" << std::endl; 
    for (int i = 0; i < n; i++) map[gen_random(len)]++; 

    if (map.size() < max) 
    { 
     std::cout << ">>MAP" << std::endl; 
     for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; 
    } 

    std::cout << ">>POPULATING VEC" << std::endl; 
    std::vector<prop> vec; 
    vec.reserve(map.size()); 
    for (auto &p : map) vec.push_back(prop(p.first, p.second)); 

    if (map.size() < max) 
    { 
     std::cout << ">>VEC" << std::endl; 
     for (auto &p : vec) std::cout << p.s_ << " : " << p.i_ << std::endl; 
     std::cout << ">>MAP" << std::endl; 
     for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; 
    } 

    std::cout << ">>POPULATING MOV" << std::endl; 
    std::vector<prop> mov; 
    mov.reserve(map.size()); 
    for (auto &p : map) mov.push_back(prop(std::move(p.first), p.second)); 

    if (map.size() < max) 
    { 
     std::cout << ">>MOV" << std::endl; 
     for (auto &p : mov) std::cout << p.s_ << " : " << p.i_ << std::endl; 
     std::cout << ">>MAP" << std::endl; 
     for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; 
    } 

    return 0; 
} 

uscita

>>GENERATING 
>>MAP 
CBAC : 1 
BCAC : 1 
BBCC : 1 
>>POPULATING VEC 
COPIED 
COPIED 
COPIED 
>>VEC 
CBAC : 1 
BCAC : 1 
BBCC : 1 
>>MAP 
CBAC : 1 
BCAC : 1 
BBCC : 1 
>>POPULATING MOV 
COPIED 
COPIED 
COPIED 
>>MOV 
CBAC : 1 
BCAC : 1 
BBCC : 1 
>>MAP 
CBAC : 1 
BCAC : 1 
BBCC : 1 
Program ended with exit code: 0 
+0

Solo il * tasto *, e non i dati per quel tasto? –

+0

Sì, solo la chiave. Potrei anche accontentarmi di spostare la coppia, però. – senseiwa

risposta

5

Non è possibile spostare, le chiavi verranno copiati, dal momento che

value_type std::pair<const Key, T> 

http://en.cppreference.com/w/cpp/container/unordered_map così, qui

for (auto &p : map) 

p verrà dedotto a std::pair<const std::string, int>.

+4

Ma abbiamo provato a permetterlo: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf –