I have a std::multimap<int, X*>
where X
is a user-defined type. I want to find a specific key-value-pair within this multimap (i.e. an iterator pointing to this pair).
(A) Complete Example:
#include <map>
#include <algorithm>
class X {};
int main()
{
X myX;
std::multimap<int, X*> myMap;
auto it = std::find(myMap.begin(), myMap.end(), std::make_pair(5, &myX));
return 0;
}
However, this does not compile (gcc 12.2.1 with -std=gnu++2a
):
no match for ‘operator==’ (operand types are ‘std::pair<const int, X*>’ and ‘const std::pair<int, X*>’)
So it seems to me somehow int
gets converted to const int
.
(B) Using std::find_if
with a lamdba function with const int
, the code compiles:
auto it = std::find_if(myMap.begin(), myMap.end(), [myX](std::pair<const int, X*>& node){ return 5 == node.first && (&myX) == node.second; } );
Questions:
const int
and not int
?Why is the type of the keys in the multimap const int and not int?
Because the Key in all standard maps is immutable.
How to fix it in a more natural way than using a (complex) lambda function like in (B) or by first looking up by key and then searching within its values?
Here's a simplified example that doesn't use X*
but X
in the map:
#include <algorithm>
#include <iostream>
#include <map>
struct X {
bool operator==(const X& rhs) const { return m_value == rhs.m_value; }
int m_value;
};
int main() {
std::multimap<int, X> myMap{
{4, {1}}, {5, {2}}, {6, {3}}, {4, {4}}, {5, {5}}, {6, {6}}
};
// get the range of _Key_s equal to 5
auto [first, last] = myMap.equal_range(5);
// the lambda - here used to find the first entry with the _Value_ `X{2}`
auto cond = [](auto&& pair) { return pair.second == X{2}; };
if (auto it = std::find_if(first, last, cond); it != last)
{
auto& [k, v] = *it;
std::cout << k << ' ' << v.m_value << '\n';
}
}
If many Values may be found, just put the find_if
in a loop:
for(;(first = std::find_if(first, last, cond)) != last; ++first) {
auto& [k, v] = *first;
std::cout << k << ' ' << v.m_value << '\n';
}