【问题标题】:Const map element access常量映射元素访问
【发布时间】:2011-07-05 07:28:59
【问题描述】:

我尝试使用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 > >' 作为'_Tp& 的'this' 参数 std::map<_key _tp _compare _alloc>::operator[](const _Key&) [with _Key = int, _Tp = char, _Compare = std::less, _Alloc = std::allocator<:pair int char> >]' 丢弃限定符

使用的编译器是g++ 4.2.1

【问题讨论】:

    标签: c++ dictionary stl constants


    【解决方案1】:

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

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

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

    【讨论】:

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

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

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

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

    【讨论】:

    • C++标准是否禁止实现在库类中定义额外的非标准成员函数?
    • @Tim 我相信界面是固定的,是的。
    【解决方案3】:

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

    看到这个link

    【讨论】:

      【解决方案4】:

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

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

      我不知道at()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        • 2019-08-10
        • 1970-01-01
        • 2011-08-12
        相关资源
        最近更新 更多