令人困惑的std :: map插入行为

时间:2010-07-10 06:52:31

标签: c++ insert map

将值插入地图时会出现一些奇怪的行为:我总是在地图的末尾插入,但有时条目会出现故障。

如果我做一个简单的测试,那么我没有遇到任何问题 - 数字是否正确排序:

map<int,int> testMap;
for(int i = 0; i < 100; ++i)
{
    // everything is ordered correctly here
    testMap.insert(testMap.end(), pair<int,int>(i,i));
}

但是当我解析一个字符串并尝试以与我读取它们相同的顺序插入值时,事情就不会那么好了:

const string INPUT_TWO =
"=VAR STRING1 \"MYSTRING\"\n\
=VAR STRING2 \"EXAMPLE\"\n\
=VAR NUMBER1 12345\n\
=VAR NUMBER2 23456\n\
=VAR DUMMY 1111\n";

const string VAL_STRING = "VAR";

vector<pair<string, string>> parse_fields(const string & input)
{
    map<string, string> fieldsMap;
    vector<pair<string, string>> sequenceFields;
    vector<string> lines = split(input, '\n');
    for(size_t i = 0; i < lines.size(); ++i)
    {
        if(lines[i].find(VAL_STRING)!=string::npos)
        {
            vector<string> vals = split(lines[i], ' ');
            if(vals.size()==3)
            {
                fieldsMap.insert(fieldsMap.end(), pair<string,string>(vals[1], remove_quotes(vals[2])));
                sequenceFields.push_back(pair<string,string>(vals[1], remove_quotes(vals[2])));
            }
        }
    }

    // at the end the map looks like:
    // "DUMMY", "1111"
    // "NUMBER1", "12345"
    // "NUMBER2", "23456"
    // "STRING1", "MYSTRING"
    // "STRING2", "EXAMPLE"

    // the vector of pairs looks like:
    // "STRING1", "MYSTRING"
    // "STRING2", "EXAMPLE"
    // "NUMBER1", "12345"
    // "NUMBER2", "23456"
    // "DUMMY", "1111"

    return sequenceFields;
}

供您参考,我已将所有其他代码粘贴到pastie

有人知道为什么会这样吗?

2 个答案:

答案 0 :(得分:4)

std::map是一个有序的容器,它允许它具有查找时间。如果您同时需要映射和列表,请考虑使用Boost.MultiIndex

答案 1 :(得分:1)

地图本身并非订购。从概念上讲,它们代表了键值对。但是C ++ std::map映射是内部排序的。见http://www.cplusplus.com/reference/stl/map/。因此,条目将按键值有效排序。

如果您需要自己的订购,则应使用元组列表。或unordered_map,如果您有hash_map; {{1}}可能在您的平台上提供)。或者在检索结果时对结果进行排序。