Is there a way to iterate over the keys, not the pairs of a C++ map?
Is there a way to iterate over the keys, not the pairs of a C++ map?
With C++17 you can use a structured binding inside a range-based for loop (adapting John H.'s answer accordingly):
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> myMap;
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
for ( const auto &[key, value]: myMap ) {
std::cout << key << '\n';
}
}
Unfortunately the C++17 standard requires you to declare the value variable, even though you're not using it (std::ignore as one would use for std::tie(..) does not work, see this discussion).
Some compilers may therefore warn you about the unused value variable! Compile-time warnings regarding unused variables are a no-go for any production code in my mind. So, this may not be applicable for certain compiler versions.
for(auto const& [key, value]: m_map)
{
std::cout<<" key="<<key;
std::cout<<" value="<<value<<std::endl;
}
With C++20, we have access to the ranges library, which has a nifty solution for this: std::views::keys
#include <ranges>
//...
std::map<int, int> myMap = {{1,2},{3,4},{5,6}};
auto keys = std::views::keys(myMap);
for(auto key : keys) {
std::cout << key << std::endl;
}
Try it out yourself: https://godbolt.org/z/heeWv4Gh6
I've adopted Ian's answer to work with all map types and fixed returning a reference for operator*
template<typename T>
class MapKeyIterator : public T
{
public:
MapKeyIterator() : T() {}
MapKeyIterator(T iter) : T(iter) {}
auto* operator->()
{
return &(T::operator->()->first);
}
auto& operator*()
{
return T::operator*().first;
}
};