2

这是我的第一个问题:)

我将程序的配置存储在一个Group->Key->Value表单中,就像旧的 INI 一样。我将信息存储在一对结构中。

第一个,我使用std::map字符串+ptr 作为组信息(字符串键中的组名)。第二个std::map值是指向第二个结构的指针,a std::listof std::maps,带有完成Key->Value对。

Key->Value 对结构是动态创建的,所以配置结构是:

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

好吧,我正在尝试实现两种方法来检查内部配置中是否存在数据。第一个,检查结构中是否存在组:

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,并考虑我正在做它作为一个练习,我知道有很多很酷的配置管理器。

4

3 回答 3

2

keyValueIt 不是映射迭代器,它是列表迭代器。你可以做

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

如果您只想要一个group/key/value结构,那么您将其过度复杂化,那么您的数据结构中需要多一层。不需要
额外的, a of就足够了:listmapmaps

// 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 回答