c++ 为什么我不能在const std::map中使用operator[]访问元素?

14ifxucb  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(132)

我尝试使用operator[]访问const map中的元素,但是这个方法失败了。我也尝试使用at()做同样的事情。这次成功了。但是我找不到任何关于使用at()访问const map中的元素的参考资料。at()map中新添加的功能吗?我在哪里可以找到更多关于这个的信息?非常感谢!
例如:

#include <iostream>
#include <map>

int main()
{
    std::map<int, char> A;
    A[1] = 'b';
    A[3] = 'c';

    const std::map<int, char> B = A;

    std::cout << B.at(3) << std::endl; // it works
    std::cout << B[3] << std::endl;    // it does not work
}

字符串
对于使用B[3],它在编译期间返回以下错误:
t01.cpp:14:错误类型:将“const std::map<int,char,std::less,std::allocator<std::pair<const int,char> >"作为”_Tp& std::map<_Key,_Tp,_Compare,_Alloc>::operator[](const _Key&)[with _Key = int,_Tp = char,_Compare = std::less,_Alloc = std::allocator<std::pair<const int,char> >]“的”this“参数传递将丢弃限定符。
使用的编译器是g++ 4.2.1

efzxgjgh

efzxgjgh1#

at()是C++11中std::map的新方法。
它不是像operator[]那样在给定键的元素不存在时插入一个新的默认构造元素,而是抛出一个std::out_of_range异常(这类似于at()dequevector的行为)。
由于这种行为,at()const过载是有意义的,不像operator[]总是有可能改变Map。

hof1towb

hof1towb2#

如果一个元素在map中不存在,operator []会添加它--这显然不能在constMap中工作,所以C没有定义const版本的操作符。这是一个很好的例子,说明编译器的类型检查器可以防止潜在的运行时错误。
在你的例子中,你需要使用find来代替,它将 * 只 * 返回一个(iterator to the)元素,如果它存在,它将永远不会修改map。如果一个项目不存在,它将返回一个iterator到map的end()
at不存在,甚至不应该编译。也许这是一个“编译器扩展”(= C
0x中的新错误)。

5lwkijsr

5lwkijsr3#

如果给定的键不存在,[]-操作符将在Map中创建一个 * 新条目 *。因此,它可能会改变Map。
看看这个link

cgh8pdjw

cgh8pdjw4#

这让我很惊讶,但是STL map没有const索引操作符。也就是说,B[3]不能是只读的。从手册中:
Since operator[] might insert a new element into the map, it can't possibly be a const member function.
我不知道at()

8ulbf1ek

8ulbf1ek5#

std::map::operator[]没有const-限定符,这意味着你不能用const std::map来调用它。如果你不熟悉这个,请参阅What is the meaning of 'const' at the end of a member function declaration?
operator[]返回对元素的引用,就像at一样,但有一个关键的区别:

因为at()不需要修改map,所以它有一个const重载:

T& at( const Key& key );
const T& at( const Key& key ) const; // <-- this is what operator[] is lacking

字符串

std::map中的非变异访问

除了这两个函数,还有三种方式可以访问const std::map中的元素:

const std::map<K, V> map = { /* ... */ };

auto a = map.at(key);   // OK, C++11, throws exception if key not found
auto b = map.find(key); // OK, returns iterator (possibly equal to .end() if key not found)

auto c = map.count(key);    // OK, returns size_type (0 or 1)
auto d = map.contains(key); // OK, C++20, returns bool

相关问题