C++中const std::map引用无法编译通过。

17

把一个 std::map 的引用作为 const 传递会导致 [] 运算符出现问题,这是有原因的吗?当我使用 const 时,我得到了这个编译器错误(gcc 4.2):

error: no match for ‘operator[]’ in ‘map[name]’

以下是函数原型:

void func(const char ch, std::string &str, const std::map<std::string, std::string> &map);

此外,我应该提到,当我删除std::map前面的const关键字时,就没有问题了。

如果我被正确告知,[]运算符实际上会在找不到键时向映射中插入新对,这当然可以解释为什么会发生这种情况,但我无法想象这种行为在任何情况下都是可接受的。

如果有更好的方法,例如使用find而不是[],我将不胜感激。但是我似乎也无法使find正常工作...我收到const不匹配的迭代器错误。

5个回答

27

是的,你不能使用operator[]。使用find,但请注意它返回的是const_iterator而不是iterator

std::map<std::string, std::string>::const_iterator it;
it = map.find(name);
if(it != map.end()) {
    std::string const& data = it->second;
    // ...
}

这就像指针一样。你不能将 int const* 分配给 int*。同样地,你也不能将 const_iterator 分配给 iterator


8

当你使用operator[]时,std::map会查找具有给定键的项。如果没有找到任何项,则会创建该项。因此const的问题就出现了。

使用find方法就可以解决这个问题。

请问您可以发布一下您尝试使用find()的代码吗? 正确的方式应该是:

if( map.find(name) != map.end() )
{
   //...
}

4
如果您正在使用C++11,std::map::at 应该适用于您。 std::map::operator[] 不起作用的原因是,在映射中找不到您要查找的键时,它将使用提供的键插入一个新元素并返回对其的引用(有关详细信息,请参见链接)。这在const std::map上是不可能的。
然而,“at”方法将抛出一个异常,如果键不存在。话虽如此,在尝试使用“at”方法访问元素之前,最好使用std::map::find方法检查键是否存在。

2

可能是因为std::map中没有const operator[]。如果它找不到你要查找的元素,operator[]将添加该元素。因此,如果您想进行搜索而不希望添加任何元素,请使用find()方法。


2

针对“const mismatched iterator errors”问题:

find()函数有两种重载形式:

      iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;

我的猜测是,您出现了这个错误,是因为您正在执行类似将非const迭代器(在左侧)分配给const map上find()调用结果的操作:

iterator<...> myIter /* non-const */ = myConstMap.find(...)

那将导致错误,尽管可能不是您看到的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接