Разместить непосредственно в std::map пары
Почему этот код не скомпилируется?
std::map<int,std::pair<int,int>> m;
m.emplace(1,1,1);
Предполагая, что мы можем редактировать код std::map::emplace
Можно ли изменить его, чтобы сделать предыдущий код действительным?
1 ответ
Это недействительно по той же причине, что и недействительно:
std::pair<const int, std::pair<int, int>> p{1, 1, 1};
Потому что выше, по сути, то, что карта emplace
сводится к.
Чтобы заставить его работать, вы можете использовать piecewise_construct
конструкторstd::pair
, который был введен именно для этой цели:
m.emplace(
std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(1, 1)
);
Это будет иметь желаемый эффект, не вызывая ненужных конструкторов (даже если они, скорее всего, будут исключены).
Чтобы ответить на ваш гипотетический вопрос о том, как заставить работать "прямой" синтаксис: в общем случае для произвольного map<K, V>
нет Вообразите это:
struct Proof {
Proof(int);
Proof(int, int);
};
std::map<Proof, Proof> m;
m.emplace(1, 1, 1); // Now what?
Вы, конечно, могли бы сделать это для ограниченного случая map<T, std::pair<T, T>>
, Вероятно, это было бы выполнимо для чего-то более общего, с помощью огромного количества продвинутых шаблонных приемов (например, SFINAE влево, вправо и в центре, а затем некоторые). Стоит ли это того, зависит от деталей вашей ситуации.