У меня есть карта:
std::map<std::string, MyDataContainer>
MyDataContainer
это какой-то class
или же struct
(не имеет значения). Теперь я хочу создать новый контейнер данных. Допустим, я хочу сделать это с доступным конструктором по умолчанию:
// This is valid, MyDataContainer doesn't need constructor arguments
MyDataConstructor example;
// The map definition
std::map<std::string, MyDataContainer> map;
std::string name("entry");
// This copies value of `example`
map[name] = example;
// Below, I want to create entry without copy:
std::string name2 = "nocopy"// This is pseudo-syntax
map.createEmptyEntry(name2);
Есть ли способ сделать это? Чтобы пропустить создание вспомогательной переменной, когда я просто хочу инициализировать ее в карте? И было бы возможно сделать это с аргументами конструктора?
Я думаю, что этот вопрос также относится к другим стандартным контейнерам, таким как stdvector или же stdlist.
использование emplace
:
#include <map>
#include <string>
#include <tuple>
std::map<std::string, X> m;
m.emplace(std::piecewise_construct,
std::forward_as_tuple("nocopy"),
std::forward_as_tuple());
Это обобщает произвольные аргументы конструктора для нового значения ключа и сопоставленного значения, которые вы просто вставляете в соответствующие forward_as_tuple
звонки.
В C ++ 17 это немного проще:
m.try_emplace("nocopy" /* mapped-value args here */);
Вы можете использовать map::emplace
: увидеть документация
m.emplace(std::piecewise_construct,
std::forward_as_tuple(42), // argument of key constructor
std::forward_as_tuple()); // argument of value constructor