2

それが私の最初の質問です:)

プログラムの構成をGroup->Key->Value古いINIのような形式で保存しています。情報を一対の構造に保存しています。

最初std::mapに、グループ情報(文字列キーのグループ名)にwith string+ptrを使用しています。2番目の値は、フィニッシュペアを持つsのstd::mapsencond構造体へのポインターです。std::liststd::mapKey->Value

キー->値のペア構造は動的に作成されるため、構成構造は次のようになります。

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

さて、私は内部構成のデータの存在をチェックするために2つのメソッドを実装しようとしています。1つ目は、構造内のグループの存在を確認します。

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

2番目の方法は、私を夢中にさせることです...グループ内のキーの存在をチェックします。

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’|

ただし、マップイテレータであるため、2番目のメンバーが必要です...

何が起こっているのかについて何か提案はありますか?

私の英語:Pについて申し訳ありませんが、これを演習として行っていると考えてください。クールな構成マネージャーがたくさんいることを知っています。

4

3 に答える 3

2

keyValue マップ イテレータではなく、リスト イテレータです。あなたはただすることができます

if (keyValueIt->find(d) != keyValueIt->end())
于 2010-03-26T12:32:17.590 に答える
1

group/key/value過度に複雑な構造が必要な場合は、データ構造にもう 1 つのレベルが必要になります。
追加listは必要ありません。mapofmapsで十分です。

// 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());
}
于 2010-03-26T13:11:57.620 に答える
1

ジョエルは正しいと思います

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 がおそらく誤用されていることがより明確になります (つまり、実際には KeyValueMap イテレーターではなくリスト イテレーターなので、'.second' アクセスは誤りです)。

于 2010-03-26T13:17:01.933 に答える