Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can';无法从指针访问映射成员_C++_Pointers_List_Iterator_Stdmap - Fatal编程技术网

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
,具有finish
Key->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;
}