为什么STL映射的[]运算符不是?

Run*_*ble 81 c++ const

举例说明,为了这个问题:

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map[x] << std::endl
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为[]运算符是非const的.

这很不幸,因为[]语法看起来很干净.相反,我必须做这样的事情:

void MyClass::MyFunction( int x ) const
{
  MyMap iter = m_map.find(x);
  std::cout << iter->second << std::endl
}
Run Code Online (Sandbox Code Playgroud)

这一直困扰着我.为什么[]运算符是非常量的?

Ala*_*lan 82

对于std::mapstd::unordered_map,operator[]将索引值插入到容器中(如果先前不存在).这有点不直观,但就是这样.

由于必须允许它失败并插入默认值,因此不能const在容器的实例上使用该运算符.

http://en.cppreference.com/w/cpp/container/map/operator_at

  • 这是正确的答案,但是 const 版本可以做与“at”成员相同的事情。那就是抛出一个 std::out_of_range ... (3认同)
  • `std :: set`没有`operator []`. (2认同)
  • 当用于读取值时,不提供默认值。`std::vector` 有一个读取运算符 `[]`,即 `const`。`map` 应该做同样的事情。 (2认同)

Deq*_*ing 47

现在使用C++ 11,您可以使用at()获得更清晰的版本

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map.at(x) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`map`有const和非const`at()`s - 为什么不同样的`operator []`?与const版本没有插入任何东西,而是投掷?(或者当std :: optional进入标准时返回一个可选项) (4认同)

Mar*_*ork 27

新读者注意事项.
最初的问题是关于STL容器(没有具体关于std :: map)

应该注意的是,大多数容器上都有一个const版本的operator [].
只是std :: map和std :: set没有const版本,这是实现它们的底层结构的结果.

来自std :: vector

reference       operator[](size_type n) 
const_reference operator[](size_type n) const 
Run Code Online (Sandbox Code Playgroud)

另外,对于第二个示例,您应该检查是否找不到该元素.

void MyClass::MyFunction( int x ) const
{
    MyMap iter = m_map.find(x);
    if (iter != m_map.end())
    {
        std::cout << iter->second << std::endl
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `std::set` 根本没有 `operator[]`。 (2认同)