2013-11-21 17 views
5

Szukałem, ale znalazłem tylko pytania dotyczące konstruktora ruchu z wartością zamapowaną na wartość , ale chcę spróbować czegoś innego.Przenoszenie kluczy z unordered_map

Czy można użyć std::move klucz klucz z std::unordered_map? Powód jest dość prosty: chciałbym stworzyć przykład, w którym tworzę wektor z mapy, marnując jak najmniej pamięci. Wiem, że to zepsułoby reprezentację mapy, ale hej, w końcu nigdy nie użyję mapy ponownie, więc sensowne byłoby przenoszenie wartości.

Zgaduję, że: nie, nie mogę tego zrobić. Chciałbym jednak potwierdzenia.

Oto prosty kod. Spodziewałem się wywołania konstruktora ruchu, ale mam wywoływanego konstruktora kopiowania.

Pozdrawiam & Dzięki!

#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; 
} 

wyjście

>>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

Tylko klucz *, a nie dane dla tego klucza? –

+0

Tak, tylko klucz. Mógłbym też zadowolić się przemieszczaniem pary. – senseiwa

Odpowiedz

5

Nie można przenieść, klucze zostaną skopiowane, ponieważ

value_type std::pair<const Key, T> 

http://en.cppreference.com/w/cpp/container/unordered_map Więc tutaj

for (auto &p : map) 

p zostanie wydedukowane jako std::pair<const std::string, int>.

+4

Ale staraliśmy się na to pozwolić: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf –

Powiązane problemy