First I have codes like
typedef struct st_A{
int a = 0;
string s;
st_A(const int a, const string&s) :a(a),s(s) {}
}st_A;
map<string, st_A> m1;
Now I want to insert a new element of pair{"c1", st_A{10, "c"}} into this map, so I code like
if (auto it = m1.find("c1"); it == m1.end()){
//not find
m1.insert({ "c1", {10, "c"} });
}else{
....update by using it....
}
But replacing by try_emplace I think it would be more concise and efficient
auto [it, inserted] = m1.try_emplace("c1", 10, "c");
if (!inserted) {
....update by using it....
}
So is it really more efficient in the form try_emplace than the one of find+insert?
And if my original map changes into map<string, map<int, st_A>> m2, now I want to insert insert a new element of pair{"c1", pair{1, st_A{10, "c"}}}; if I still insist on using try_emplace,but it would be ill-formed like
auto [it, inserted] = m1.try_emplace("c1", 1, 10, "c");
So would it still be suitable this time if using try_emplace, and how?
try_emplacedoes an unique look-up and potentially contruct in-place.find+insertdo 2 look-up and use copy/move constructor.Another alternative would be
lower_bound+insert(with hint) to reduce the look-up to one, but it would need extra check to see if found iterator is the value or not.So
try_emplacewin in all circumstance.mapcannot be construct frompair(but frominitializer_list<pair<..>>).{..}has not type, so is problematic intry_emplaceas-is.so it would be:
With the caveat that
initializer_listcontent isconst, so require a copy and not a move.You might create a proxy type o construct the map only on demand, something like:
and
Demo