2013-11-21 6 views
5

Ich habe gesucht, aber ich habe nur Fragen über Move Constructor mit dem zugeordneten Wert gefunden, aber ich möchte etwas anderes ausprobieren.Verschieben von Schlüsseln aus unordered_map

Ist es möglich, std::move der Schlüssel von einem std::unordered_map zu verwenden? Der Grund ist ziemlich einfach: Ich möchte ein Beispiel konstruieren, bei dem ich einen Vektor aus der Karte erzeuge und so wenig Speicher wie möglich verschwende. Ich weiß, dass es mit der Darstellung der Karte zu tun haben würde, aber hey, schließlich werde ich die Karte nie wieder benutzen, daher wäre es sinnvoll, Werte zu verschieben.

Meine Vermutung ist dies: Nein, das kann ich nicht tun. Allerdings hätte ich gerne eine Bestätigung.

Hier ist ein einfacher Code. Ich habe erwartet, dass der Move-Konstruktor aufgerufen wird, aber ich habe den Copy-Konstruktor aufgerufen.

Prost & Danke!

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

Ausgang

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

Nur der * Schlüssel *, und nicht die Daten für diesen Schlüssel? –

+0

Ja, nur der Schlüssel. Ich könnte mich aber auch damit begnügen, das Paar zu bewegen. – senseiwa

Antwort

5

Sie können sich nicht bewegen, werden Schlüssel kopiert werden, da

value_type std::pair<const Key, T> 

http://en.cppreference.com/w/cpp/container/unordered_map so, hier

for (auto &p : map) 

p wird zu std::pair<const std::string, int> abgeleitet.

+4

Aber wir haben versucht, es zu erlauben: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf –