这是我的第一个问题:)
我将程序的配置存储在Group->Key->Value
表单中,就像旧的INI一样。我将信息存储在一对结构中。
首先,我使用std::map
字符串+ ptr作为组信息(字符串键中的组名)。第二个std::map
值是指向sencond结构的指针,std::list
std::map
个,结束Key->Value
对。
Key->值对结构是动态创建的,因此配置结构为:
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,并且考虑我正在做这个练习,我知道有很多很酷的配置管理器。
答案 0 :(得分:2)
keyValueIt不是map迭代器,它是一个列表迭代器。 你可以做到
if (keyValueIt->find(d) != keyValueIt->end())
答案 1 :(得分:1)
如果您只想要一个group/key/value
结构,那么您的数据结构会过于复杂,那么您需要在数据结构中增加一个级别。
不需要额外的list
,只需map
maps
就足够了:
// 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());
}
答案 2 :(得分: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'访问是错误的。)