1. ホーム
  2. c++

[解決済み] unordered_map をどのように反復処理するか?

2022-02-15 09:49:17

質問

順不同のマップのメンバーを反復処理したいだけなのですが。

このサイトも含め、ウェブ上には簡単な例がたくさんありますが、どれもコンパイルできません。 どうやら、ある例は以前の非標準STLバージョンのもので、ある例は単に古いもので、ある例は私のgcc 4.7.2では扱えないほど新しいものであるようです。 C++11からの新しい自動イテレータを提案しないでください。 私のライブラリがすべて検証されたら、いつかそこに到達します。 それまでは、古いものが動作するようにしたいのです。 (私が試したことは以下を参照してください)

以下は私のテストコードです。

#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;
}

エラーのほとんどは、このバリエーションです。

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

以下は、私のビルドコマンドです。

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

このような初心者の質問で行き詰まるのは恥ずかしいことですが、似たような質問の量からすると、これは多くの人が足を止めるだけの難しさだと思います。 私は以前ハッシュコンテナを書いたことがあり(STLを使わないことが推奨されていた頃)、自分で書いてみたいという気持ちに駆られます...しかし、正しいことは、できるだけ多くの既存のツールを使うことを学ぶことです...助けてください

stackoverflowで以下の質問を見てみましたが、回答が見つかりませんでした。

boost_foreach を使って unordered_map を反復処理する。

試してみました。

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

というエラーが出てしまいます。

Unordered_map イテレータの無効化

これは近いですが、私の問題とはちょっと違います。

boost::unordered_map でのイテレータの無効化

こちらはautoを使用します。 で、現時点ではコンパイラを切り替えることができません。

C++ boost::unordered_map & boost::hash に関するいくつかの質問

<ブロッククオート

こちらは主に写像の理論についてです。

boost::unordered_mapの使い方

<ブロッククオート

これはかなり複雑な例ですが、私のコードではすでにイテレータを宣言しようとしているのがわかるでしょう...ただ、コンパイルできないだけなのです。

BOOST_FOREACHをUnordered_mapで使用するには?

<ブロッククオート

これはいい例ですが が、どうしてもコンパイルできません。 私のコードでこれを再現してみました。

うまくいった

以下は、動作するコードです。

#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;
    }

構文エラーでした。 イテレータを宣言するときに型を入れる場所を間違えていたのです。

皆さん、ご回答ありがとうございました。

どのように解決するのですか?

を変更してみてください。 boost::unordered::unordered_map::iterator it; に変更します。 boost::unordered::unordered_map<std::string,int>::iterator it;

注 より複雑な状況では、次のような型定義を作成することも可能であり、良いアイデアです。 typedef boost::unordered::unordered_map<std::string,int>::iterator UMapStringIntIt; などと呼ばれることがあります。