Search code examples
c++dictionaryemplace

C++ how to use emplace in std::map using forwarding argument


With an std::vector I've managed to use emplace_back by forwarding the arguments, as in this code:

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

using namespace std;

struct Complicated
{
  int i;
  double d;
  string s;

 Complicated(int a, double b, std::string c): i{a}, d{b}, s{c}{};
};

int main()
{
  std::vector<Complicated> m;
  int anInt = 4;
  double aDouble = 5.0;
  std::string aString = "C++";

  m.emplace_back(anInt,aDouble,aString);
  return 0;
}

Something similar should happen with a map:

  std::map<int, Complicated> m;
  int anInt = 4;
  double aDouble = 5.0;
  std::string aString = "C++";

  m.emplace(4,anInt,aDouble,aString);

but I am getting the following error:

emplace_back.cpp:28:39:   required from here
/usr/include/c++/9/ext/new_allocator.h:146:4: error: no matching function for call to ‘std::pair<const int, Complicated>::pair(int, int&, double&, std::__cxx11::basic_string<char>&)’
  146 |  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

How can I do that?


Solution

  • You can use the std::pair constructor taking a std::piecewise_construct_t for this scenario:

    m.emplace(std::piecewise_construct,
              std::forward_as_tuple(4),
              std::forward_as_tuple(anInt, aDouble, aString));