C++ Can';无法从指针访问映射成员
这是我的第一个问题:) 我将程序的配置存储在C++ Can';无法从指针访问映射成员,c++,pointers,list,iterator,stdmap,C++,Pointers,List,Iterator,Stdmap,这是我的第一个问题:) 我将程序的配置存储在Group->Key->Value表单中,就像旧的INIs一样。我将信息存储在一对结构中 首先,我使用了一个std::map和string+ptr作为组信息(字符串键中的组名)。第二个std::map值是指向第二个结构的指针,它是std::maps的std::list,具有finishKey->value对 键->值对结构是动态创建的,因此配置结构是: std::map< std::string , std::list< std::map&
Group->Key->Value
表单中,就像旧的INIs一样。我将信息存储在一对结构中
首先,我使用了一个std::map
和string+ptr作为组信息(字符串键中的组名)。第二个std::map
值是指向第二个结构的指针,它是std::map
s的std::list
,具有finishKey->value
对
键->值对结构是动态创建的,因此配置结构是:
std::map< std::string , std::list< std::map<std::string,std::string> >* > lv1;
第二种方法,就是让我发疯。。。它检查组中是否存在密钥
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;
}
bool-isconfig-glv2(std::string,std::string);
bool ConfigManager::isconfig glv2(std::string s,std::string d){
如果(!isConfigv1(s))
返回false;
std::map*>::迭代器;
std::list*键值;
std::list::迭代器keyValueIt;
它=1级。查找(s);
keyValue=(*it);
对于(keyValueIt=keyValue->begin();keyValueIt!=keyValue->end();keyValueIt++)
if(!((*keyValueIt.second.find(d)=(*keyValueIt.second.end()))
返回true;
返回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’|
ConfigManager.cpp | |在成员函数“bool-ConfigManager::isConfigLv2(std::string,std::string)”中:|
ConfigManager.cpp |(返回true上方的行)|错误:“class std::map”没有名为“second”的成员|
但它必须有第二个成员,因为它是一个映射迭代器
对发生的事情有什么建议吗
对不起,我的英文是:P,并且我把它当作一个练习来做,我知道有很多很酷的配置管理器。 KEYVALIVE它不是一个映射迭代器,它是一个列表迭代器。 你可以这么做
if (keyValueIt->find(d) != keyValueIt->end())
如果您只是想要一个
组/键/值
结构,那么您的数据结构就过于复杂了,您还需要一个级别。不需要额外的
列表
,一个映射
的映射就足够了:
// 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());
}
//typedefs的可读性:
typedef std::映射条目;
typedef std::映射组;
//班级成员:
组m_组;
bool ConfigManager::hasKey(常量std::string和group,常量std::string和key)
{
Groups::const_迭代器it=m_Groups.find(group);
if(it==m_groups.end())
返回false;
const Entries&Entries=it->second;
return(entries.find(key)!=entries.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;
}
typedef std::map KeyValueMap;
typedef std::listConfigurationList;
typedef std::mapConfigurationMap;
bool-isconfig-glv2(std::string,std::string);
bool ConfigManager::isconfig glv2(std::string s,std::string d){
如果(!isConfigv1(s))
返回false;
ConfigurationMap::iterator;
配置列表*键值;
ConfigurationList::迭代器keyValueIt;//开始();keyValueIt!=keyValue->end();keyValueIt++)
if(!((*keyValueIt.second.find(d)=(*keyValueIt.second.end()))
返回true;
返回false;
}
简化类型使我更清楚地看到keyValueIt可能被误用了(即,它实际上是一个列表迭代器,而不是KeyValueMap迭代器,因此“.second”访问是错误的。)它不是一个列表::迭代器,而是一个列表::迭代器。它找不到d。*keyValueIt
提供了一个映射
,您可以在上面使用map::find(key)
。Ok。我要走乔尔的路。另外,我可以替换:return!(lv1.find=lv1.end())代码>用于:返回1级。查找=lv1.end()代码>在第一个检查方法中。谢谢你们!如果一段代码曾经要求使用一些经过明智选择的typedef
语句,那么就是这样。不要忘记对有用的答案进行投票;)(我并不是说你必须投票支持某个答案,只是投票是SO的核心功能之一——详情请参见常见问题解答。)PS我的typedef名称非常垃圾。花时间想出好的、描述性的名字是值得的:)别担心,这个想法是正确的。gf在下一篇评论中回复得很好。谢谢。现在我正在做类似的事情;)
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;
}