简体   繁体   中英

how to iterate through boost unordered_map?

I just want to iterate through the members of an unordered map.

There are many simple examples on the web, including on this site, and yet none of them will compile. Apparently some examples are from a previous non-standard STL version, some are just old, and some are so new that my gcc 4.7.2 can't handle them. Please do not suggest the new auto iterator from C++11. I will get there some day when all my libraries are validated for that. Until then, I just want the old one to work. (see below for what I have tried)

Here is my test code:

#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>

int main(int argc,char *argv[]) {
    boost::unordered::unordered_map<std::string,int> umap;

    //can't get gcc to accept the value_type()...
    //umap.insert(boost::unordered_map::value_type("alpha",1));
    //umap.insert(boost::unordered_map::value_type("beta",2));
    //umap.insert(boost::unordered_map::value_type("gamma",3));

    umap["alpha"]=1; //this works
    umap["beta"]=2;
    umap["gamma"]=3;

    //can't get gcc to compile the iterator
    //for (boost::unordered_map::iterator it=umap.begin();it!=umap.end();++it)
    //  std::cout << it->first <<", " << it->second << std::endl;

    //gcc does not like it this way either
    //for (int x=0;x<umap.size();x++)
    //  std::cout << x << " : " << umap[x].first << " = " << umap[x].second << std::endl;

    //will gcc take this? No it does not
    //for (int x=0;x<umap.size();x++)
    //  std::cout << x << " : " << umap[x] << std::endl;

    //this does not work
    //boost::unordered::unordered_map::iterator<std::string,int> it;

    //this does not work
    //boost::unordered::unordered_map::iterator it;
    //for (it=umap.begin();it!=umap.end();++it)
    //  std::cout << it->first <<", " << it->second << std::endl;

    //this does not work
    //BOOST_FOREACH(boost::unordered_map::value_type value, umap) {
    //  std::cout << value.second;
    //  }
    //std::cout << std::endl;

    //this does not work either
    //BOOST_FOREACH(boost::unordered_map::value_type<std::string,int> value, umap) {
    //  std::cout << value.second;
    //  }
    //std::cout << std::endl;

    std::cout << "umap size: " << umap.size() << std::endl;
    std::cout << "umap max size: " << umap.max_size() << std::endl;
    std::cout << "find alpha: " << (umap.find("alpha")!=umap.end()) << std::endl;
    std::cout << "count beta: " << umap.count("beta") << std::endl;
}

Most of the errors are a variation of this:

error: 'template<class K, class T, class H, class P, class A> class boost::unordered::unordered_map' used without template parameters

Here is my build command:

g++ -I..\boost umap.cpp

I should be embarrassed for getting stuck on such a beginner's question, but from the volume of similar questions I am finding, this is just hard enough to stop a lot of people in their tracks. I have written hash containers before (back when it was recommended NOT to use STL) and I am very tempted to just write my own... but the right thing to do is learn to use as many existing tools as possible... help!

I've looked at the following questions on stackoverflow where I haven't found an answer:

iterate through unordered_map using boost_foreach

I tried:

 BOOST_FOREACH(boost::unordered_map::value_type& value, umap) { 

but it gives the same error I show below.

Unordered_map iterator invalidation

This one is close, but not quite my issue:

Iterator invalidation in boost::unordered_map

This one uses auto and I can't switch compilers at this time.

C++ some questions on boost::unordered_map & boost::hash

This one is mostly about the theory of maps:

how to use boost::unordered_map

This is a rather complicated example, but you will see in my code I am already trying to declare iterators... they just won't compile.

How to use BOOST_FOREACH with an Unordered_map?

This is a nice example, but it just does not compile. I tried a version of this in my code.

IT WORKS !

Here is the working code:

#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>

int main(int argc,char *argv[]) {
    boost::unordered::unordered_map<std::string,int> umap;
    umap["alpha"]=1; 
    umap["beta"]=2;
    umap["gamma"]=3;
    boost::unordered::unordered_map<std::string,int>::iterator it;
    for (it=umap.begin();it!=umap.end();++it)
        std::cout << it->first <<", " << it->second << std::endl;

    std::cout << "umap size: " << umap.size() << std::endl;
    std::cout << "umap max size: " << umap.max_size() << std::endl;
    std::cout << "find alpha: " << (umap.find("alpha")!=umap.end()) << std::endl;
    std::cout << "count beta: " << umap.count("beta") << std::endl;
    }

It was a syntax error. I was putting the type in the wrong place when declaring the iterator.

Thanks everyone for your responses.

try changing boost::unordered::unordered_map::iterator it; it to boost::unordered::unordered_map<std::string,int>::iterator it;

NOTE: It is also possible, and a good idea in more complex situations, to create a typedef of it, such as typedef boost::unordered::unordered_map<std::string,int>::iterator UMapStringIntIt; , or whatever you may call it.

The answer is in the question, but the simple solution is here for your convenience:

#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>

int main(int argc,char *argv[]) 
{
    boost::unordered::unordered_map<std::string,int> umap;
    umap["alpha"]=1; 
    umap["beta"]=2;
    umap["gamma"]=3;

    for ( auto it= umap.begin(); it != umap.end(); ++it )
        std::cout << it->first <<", " << it->second << std::endl;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM