c++stdmapemplace

How to use std::map::emplace to add a default constructed value when it is not movable


This compiles:

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = default;
};
int main() {
    std::map<int, S> values;
    values.emplace(42, S{});
}

LIVE

This does not:

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = delete;
};
class Wrapper {
   public:
    std::map<int, S> values;
    void AddEmptyValue(int key, int) { values.emplace(key, S{}); }
};

LIVE
(it's not surprising as we're building a S rvalue what would have to be moved to the second part of a std::pair but S is not movable).

How can I just pass a key and let the value be default-constructed?


Solution

  • You need to use the std::piecewise_construct tag like

    values.emplace(std::piecewise_construct,
                   std::forward_as_tuple(42),
                   std::forward_as_tuple());
    

    in order to tell emplace that the key should be constructed with 42 and the value should be constructed with nothing, which will use the default constructor.