C++11 基于范围的多图循环 - 不能 return 非常量对

C++11 range based multimap loop - cant return a non const pair

我似乎看不出自己做错了什么,有点跑题了。

我有一些包含向量和多图的数据结构。

我想让第二个 vectors/multimaps 包含指向原始数据的指针,这样如果我编辑第二个 vector/map,原始数据就会发生变化。原因是该列表是基于某些标准的 orig 的临时子集。

首先我在矢量上尝试了这个,它似乎有效,这是一个有效的例子:

std::vector<std::string> strVect;
strVect.push_back("test1");
strVect.push_back("test2");
strVect.push_back("test3");
std::vector<std::string *>strpVect;
for (std::string &str : strVect)
{
    strpVect.push_back(&str);
}

这里,strpVect中的元素指向strVect中的原始元素。

现在我想对多图做同样的事情:

std::multimap<int, std::string> strMap;
strMap.insert(std::pair<int, std::string>(1, "test1"));
strMap.insert(std::pair<int, std::string>(2, "test2"));
strMap.insert(std::pair<int, std::string>(3, "test3"));
std::multimap<int, std::string *>strpMap;
for (std::pair<int, std::string> &val : strMap)  // <<<<< error here
{
    strpMap.insert(std::pair<int, std::string *>(val.first, &val.second));
}

现在,当我 运行 这样做时,我得到错误 invalid init of non-const reference of type std::pair....

如果我将它设为 const 那么它就可以工作:

std::multimap<int, std::string> strMap;
strMap.insert(std::pair<int, std::string>(1, "test1"));
strMap.insert(std::pair<int, std::string>(2, "test2"));
strMap.insert(std::pair<int, std::string>(3, "test3"));
std::multimap<int, std::string *>strpMap;
for (const std::pair<int, std::string> &val : strMap)
{
    strpMap.insert(std::pair<int, std::string *>(val.first, &val.second));   // <<<<< error here
}

但后来我在插入时遇到错误(对我来说更明显)- 但我不想插入 const,因为我想更改其中的值....我可以放弃它,但是我认为这是我编码的失败:(

(多)映射中的键是 const。 因此,

for (std::pair<const int, std::string> &val : strMap)
{
    strpMap.insert(std::pair<int, std::string *>(val.first, &val.second));
}

应该可以解决问题。

或者,更好(恕我直言),使用 auto:

for (auto &val : strMap)
{
    strpMap.insert(std::pair<int, std::string *>(val.first, &val.second));
}

这会自动获得适合您的const

多图的值类型是pair<const key_type,mapped_type>

所以你应该可以使用它。

for (std::pair<const int, std::string> &val : strMap)
{
    strpMap.insert(std::pair<int, std::string *>(val.first, &val.second));
}

无法使用非常量版本的原因如下。

地图条目以按键排序的方式存储。如果您之后更改密钥,它仍会保留在之前的排序位置,然后即使您插入数据,查找也可能一无所获。这是因为它会查看键已插入的位置,但如果您在将键值插入列表后更改键值,则此后它不会匹配。