ChatGPT解决这个技术问题 Extra ChatGPT

常量映射元素访问

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

一个例子可能如下:

#include <iostream>
#include <map>

using namespace std;

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

        const map<int, char> B = A;

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

}

对于使用“B[3]”,它在编译过程中返回了以下错误:

t01.cpp:14: 错误: 传递 'const std::map > >' 作为 'this' 参数_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = char, _Compare = std::less, _Alloc = std::allocator >]' 丢弃限定符

使用的编译器是g++ 4.2.1


C
CB Bailey

at() 是 C++11 中 std::map 的新方法。

如果具有给定键的元素不存在,它不会像 operator[] 那样插入新的默认构造元素,而是会引发 std::out_of_range 异常。 (这类似于 dequevectorat() 行为。)

由于这种行为,at()const 重载是有意义的,这与 operator[] 不同,它总是有可能更改地图。


是否可以让“at”返回默认值而不是抛出异常?
我在设置为使用 VS2010 工具包的项目上在 VS2013 中使用 at()。我以为这意味着我没有使用 C++11……但是它编译……??
我只需要评论一下,省略 const 运算符 [] 是没有意义的,这也可能会为未映射的元素引发异常,而不是更改映射。
@Spencer 如果 operator[] 的 const 和非常量重载具有不同的效果,那将是令人惊讶的。通常,我们期望如果程序中的某些非 const 对象或引用被设为 const,只要程序能够编译,它就会继续以相同的方式运行。仅允许非常量重载引发异常可能会导致直到运行时才被捕获的错误。
@Brian 为嘈杂的错误交易一个沉默的、可能破坏性的错误。这是好事。
K
Konrad Rudolph

如果 map 中不存在某个元素,则 operator [] 将添加它——这显然不能在 const 映射中工作,因此 C++ 没有定义运算符的 const 版本。这是编译器类型检查器防止潜在运行时错误的一个很好的例子。

在您的情况下,您需要使用 find 代替它返回一个(迭代器到)元素(如果存在),它永远不会修改 map。如果项目不存在,它会返回一个指向地图 end() 的迭代器。

at 不存在,甚至不应该编译。也许这是一个“编译器扩展”(= 一个错误 C++0x 中的新功能)。


C++ 标准是否禁止实现在库类中定义额外的非标准成员函数?
@Tim 我相信界面是固定的,是的。
v
vidstige

如果给定的键不存在,[] 运算符将在映射中创建一个新条目。因此它可能会改变地图。

请参阅此link


B
Beta

这让我很吃惊,但是 STL 映射没有 const 索引运算符。也就是说,B[3] 不能是只读的。从手册:

Since operator[] might insert a new element into the map, it can't possibly be a const member function.

我不知道at()