ChatGPT解决这个技术问题 Extra ChatGPT

How to check if std::map contains a key without doing insert?

The only way I have found to check for duplicates is by inserting and checking the std::pair.second for false, but the problem is that this still inserts something if the key is unused, whereas what I want is a map.contains(key); function.


P
Potatoswatter

Use my_map.count( key ); it can only return 0 or 1, which is essentially the Boolean result you want.

Alternately my_map.find( key ) != my_map.end() works too.


@John: That reeks of premature optimization. On GCC (and I'm sure most reasonable systems), map::count is implemented as find(__x) == end() ? 0 : 1;. For multimap the you may have a performance argument, but that's not OP's question and I still prefer elegance.
No, the premature optimization argument is only valid if the optimization takes some effort which in this case it does not.
Not true. It's not premature if it makes the code easier to read or eliminates unnecessary overhead. In this case, if count() is implemented via find() anyway, then calling find() directly eliminates a function call... ergo, it's mature optimization. I find that using the find() call is more obvious, as well, but that's purely personal preference.
It is not a premature optimization to be aware of the perf of library functions before you make a habit of using them. In this case, you're right, it doesn't matter, but neither does the minuscule stylistic difference between find and count. I think you take the 'premature optimization' rhetoric too far. You should take any "free" optimization habits you can find and use them for everyday development. It's when coders succumb to the trap of paying costs in readability/dev time/etc, all for unmeasured "performance gains" that the premature optimization rhetoric becomes the right advice to give.
Far out, std should just add a damn has(k) / contains(k) like every other sane map class on the planet. Poor interface design. The find() approach is too verbose and the count(k) approach is definitely not at semantic parity with has(k). For that matter neither is find(k) . Check out the view count on this question.
C
Chris Jester-Young

Potatoswatter's answer is all right, but I prefer to use find or lower_bound instead. lower_bound is especially useful because the iterator returned can subsequently be used for a hinted insertion, should you wish to insert something with the same key.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

This is subtly different from how he says he's doing it… the only difference is that computation of value may be skipped if insertion is unnecessary.
Sure, I understand that the OP doesn't care to insert, so a lower_bound-based solution is overkill. I kind of just mentioned my answer "for completeness"; like I said, yours is perfectly adequate. :-)
Yep, this is a good answer and I don't disagree with anything. Just pointing out the relationship to the alternative of insert a priori. Actually, there is another difference if using a multimap, the lower_bound method inserts at the beginning of the equivalent range whereas the plain insert method adds to the end of the range.
Not the answer to the question, but my poor question asking lead me to the right answer here... I need to do the insert/update. :D
@Hunter Can you show me your code? If it's not massive, I can probably review it for you.
C
Camille Goudeseune

Your desideratum,map.contains(key), was scheduled for the draft standard C++2a and implemented in C++20. In 2017 it was implemented by gcc 9.2. It's also in clang.


This is a nice feature! I think it has landed on C++20. cppreference.com