質問

:私の最初の質問です。

私は古いINISのように、Group->Key->Valueの形で私のプログラムの設定を保存しています。私は、構造体のペアの情報を格納しています。

まず一つは、私はグループの情報(文字列キーでグループ名)の文字列+ PTRとstd::mapを使用しています。第std::map値は、仕上げstd::list対を有するsencond構造体へのポインタ、std::mapsのKey->Value、である。

キー - >値対構造が動的に作成されるので、コンフィギュレーション構造は以下の通りである:

std::map< std::string , std::list< std::map<std::string,std::string> >* > lv1;

まあ、私は内部設定でデータの存在を確認するために2つのメソッドを実装しようとしています。最初のものは、構造内のグループの存在を確認します。

bool isConfigLv1(std::string);
bool ConfigManager::isConfigLv1(std::string s) {
    return !(lv1.find(s)==lv1.end());
}

第二の方法、私は狂気作っている...それはグループ内のキーの存在を確認します。

bool isConfigLv2(std::string,std::string);
bool ConfigManager::isConfigLv2(std::string s,std::string d) {
    if(!isConfigLv1(s))
        return false;
    std::map< std::string , std::list< std::map<std::string,std::string> >* >::iterator it;
    std::list< std::map<std::string,std::string> >* keyValue;
    std::list< std::map<std::string,std::string> >::iterator keyValueIt;
    it = lv1.find(s);
    keyValue = (*it).second;
    for ( keyValueIt = keyValue->begin() ; keyValueIt != keyValue->end() ; keyValueIt++ )
        if(!((*keyValueIt).second.find(d)==(*keyValueIt).second.end()))
            return true;
    return false;
}

私が間違っているのか理解していません。コンパイラは言います:

ConfigManager.cpp||In member function ‘bool ConfigManager::isConfigLv2(std::string, std::string)’:|
ConfigManager.cpp|(line over return true)|error: ‘class std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >’ has no member named ‘second’|

しかし、それはマップイテレータ...

ですので、それは、第二の部材を有していなければなりません

何が起こっているのかについての任意の提案?

申し訳ありませんが、私の英語のために:P、と私は運動としてそれをやって検討し、私はクールな構成管理者がたくさんいることを知っている。

役に立ちましたか?

解決

keyValueItは、リスト反復子で、マップのイテレータではありません。 あなただけ行うことができます。

if (keyValueIt->find(d) != keyValueIt->end())

他のヒント

私はジョエルがで正しいと思います。

if (keyValueIt->find(d) != keyValueIt->end())

しかし、私はあなたがしようとすると、あなたのコードを簡素化するため、いくつかのtypedefを使用奨励したかったのです。このような問題を診断するときのtypedefを助けることができる(そして、あなたがしているラッキーコンパイラが、結果としてあなたに、より意味のあるエラーメッセージを与える場合は使用しています。

たとえば、

typedef std::map<std::string,std::string> KeyValueMap;
typedef std::list< KeyValueMap > ConfigurationList;
typedef std::map< std::string, ConfigurationList* > ConfigurationMap;

bool isConfigLv2(std::string,std::string);
bool ConfigManager::isConfigLv2(std::string s,std::string d) {
    if(!isConfigLv1(s))
        return false;

    ConfigurationMap::iterator it;
    ConfigurationList* keyValue;
    ConfigurationList::iterator keyValueIt;  // <- it's not a keyValue iterator, it's a ConfigList iterator!
    it = lv1.find(s);
    keyValue = (*it).second;
    for ( keyValueIt = keyValue->begin() ; keyValueIt != keyValue->end() ; keyValueIt++ )
        if(!((*keyValueIt).second.find(d)==(*keyValueIt).second.end()))
            return true;
    return false;
}
タイプを簡素化することkeyValueItはおそらくmisuedされていることを私にはそれがより明確になり(すなわち、それは実際にリスト反復子ではなく、KeyValueMapイテレータと '.secondのアクセスが誤っているようです。)

あなたはちょうどあなたがそれを上に複雑にしているgroup/key/value構造をしたい場合は、

、あなたはその後、必要に応じて、あなたのデータ構造内の1つの以上のレベルを持っている。
追加listが必要とされていない、mapmapsは十分であります:

// typedefs for readability:
typedef std::map<std::string, std::string> Entries;
typedef std::map<std::string, Entries> Groups;
// class member:
Groups m_groups;

bool ConfigManager::hasKey(const std::string& group, const std::string& key) 
{        
    Groups::const_iterator it = m_groups.find(group);
    if(it == m_groups.end())
        return false;

    const Entries& entries = it->second;
    return (entries.find(key) != entries.end());
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top