无法从指针访问映射成员

发布于 2024-08-26 20:46:12 字数 2249 浏览 7 评论 0原文

这是我的第一个问题 :)

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

第一个,我使用带有 string+ptr 的 std::map 作为组信息(字符串键中的组名称)。第二个 std::map 值是指向第二个结构的指针,即 std::map 的 std::list,其中完成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,考虑到我这样做是为了练习,我知道有很多很酷的配置管理器。

That's my first question :)

I'm storing the configuration of my program in a Group->Key->Value form, like the old INIs. I'm storing the information in a pair of structures.

First one, I'm using a std::map with string+ptr for the groups info (the group name in the string key). The second std::map value is a pointer to the sencond structure, a std::list of std::maps, with the finish Key->Value pairs.

The Key->Value pairs structure is created dynamically, so the config structure is:

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

Well, I'm trying to implement two methods to check the existence of data in the internal config. The first one, check the existence of a group in the structure:

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

The second method, is making me crazy... It check the existence for a key inside a group.

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;
}

I don't understand what is wrong. The compiler says:

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

But it has to have the second member, because it's a map iterator...

Any suggestion about what's happening?

Sorry for my English :P, and consider I'm doing it as a exercise, I know there are a lot of cool configuration managers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦屿孤独相伴 2024-09-02 20:46:13

keyValue它不是一个map迭代器,它是一个列表迭代器。
你可以这样做

if (keyValueIt->find(d) != keyValueIt->end())

keyValueIt is not a map iterator, it is a list iterator.
You can just do

if (keyValueIt->find(d) != keyValueIt->end())
赏烟花じ飞满天 2024-09-02 20:46:13

我认为 Joel 是正确的,

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”访问是错误的。)

I think Joel is correct with

if (keyValueIt->find(d) != keyValueIt->end())

However I wanted to encourage you use some typedefs to try and simplify your code. Using typedefs can help when diagnosing problems like this (and if you're lucky your compiler will give you more meaningful error messages as a result.

For instance:

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;
}

Simplifying the types makes it more obvious to me that keyValueIt is probably being misued (i.e. it's actually a list iterator, and not a KeyValueMap iterator and so the '.second' access is erroneous.)

只是一片海 2024-09-02 20:46:13

如果您只想要一个组/键/值结构,那么您的结构就过于复杂了,您的数据结构中还需要一层。
不需要额外的 listmapsmap 就足够了:

// 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());
}

If you just want a group/key/value structure you are over-complicating it, you have one more level in your data structure then needed.
The additional list isn't needed, a map of maps is sufficient:

// 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());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文