为了这个问题,举例说明:
void MyClass::MyFunction( int x ) const
{
std::cout << m_map[x] << std::endl
}
这不会编译,因为[]运算符是非const的。
这很不幸,因为[]语法看起来非常干净。相反,我必须做这样的事情:
void MyClass::MyFunction( int x ) const
{
MyMap iter = m_map.find(x);
std::cout << iter->second << std::endl
}
这一直困扰着我。为什么[]运算符是非const?
答案 0 :(得分:82)
对于std::map
和std::unordered_map
,如果以前不存在,operator[]
会将索引值插入到容器中。这有点不直观,但就是这样。
由于必须允许它失败并插入默认值,因此不能在容器的const
实例上使用该运算符。
答案 1 :(得分:47)
现在,使用C ++ 11,您可以使用at()
获得更清晰的版本void MyClass::MyFunction( int x ) const
{
std::cout << m_map.at(x) << std::endl;
}
答案 2 :(得分: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
另外,对于您的第二个示例,您应该检查是否找不到该元素。
void MyClass::MyFunction( int x ) const
{
MyMap iter = m_map.find(x);
if (iter != m_map.end())
{
std::cout << iter->second << std::endl
}
}
答案 3 :(得分:3)
由于operator []可能会在容器中插入新元素,因此它不可能是const成员函数。注意,operator []的定义非常简单:m [k]等价于(*((m.insert(value_type(k,data_type())))。first))。second。严格来说,这个成员函数是不必要的:它只是为了方便而存在
答案 4 :(得分:0)
索引运算符应该只是一个只读容器的const(STL本身并不存在)。
索引运算符不仅用于查看值。
答案 5 :(得分:-1)
如果声明std :: map成员变量是可变的
mutable std::map<...> m_map;
您可以在const成员函数中使用std :: map的非const成员函数。