c++stdmapemplace

c++ std::map::emplace() doesn't work but operator[] is ok


#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <unordered_set>

using namespace std;

// 双向链表
struct ListNode {
    int times;
    unordered_set<string> bucket;
    ListNode *prev;
    ListNode *next;

    ListNode() {
        prev = nullptr;
        next = nullptr;
    }

    ListNode(int times, string key) : ListNode() {
        this->times = times;
        bucket.emplace(key);
    }
};

int main() {
    unordered_map<string, ListNode *> map;
    ListNode *node = new ListNode();
    map.emplace("haha", node);
//    map["haha"] = node;
    ListNode *node2 = new ListNode(1, "x");
    map.emplace("haha", node2);
//    map["haha"] = node2;
}

debug screenshot


Solution

  • std::map::emplace adds a new element with a given key - but only if this key does not already exists:

    Inserts a new element into the container constructed in-place with the given args, if there is no element with the key in the container.

    (emphasis is mine)

    In your case the first call to to emplace uses a new key, and therefore indeed adds an the entry to the map. But the second call to emplace uses a key which already exists, and therefore it does nothing.

    On the other hand std::map::operator[] always returns a reference to an element in the map (either the existing one, or a newly added one if it doesn't).

    Returns a reference to the value that is mapped to a key equivalent to key or x respectively, performing an insertion if such key does not already exist.

    Via this reference you can always update the value under that key as you do in the second call.