Ejemplo elaborado, por el bien de la pregunta:
void MyClass::MyFunction( int x ) const
{
std::cout << m_map[x] << std::endl
}
Esto no se compilará, ya que el operador [] no es constante.
Esto es lamentable, ya que la sintaxis [] parece muy limpia. En cambio, tengo que hacer algo como esto:
void MyClass::MyFunction( int x ) const
{
MyMap iter = m_map.find(x);
std::cout << iter->second << std::endl
}
Esto siempre me ha molestado. ¿Por qué el operador [] no es constante?

operator[]rendir en caso de que el elemento dado no exista?Respuestas:
Para
std::mapystd::unordered_map,operator[]insertará el valor del índice en el contenedor si no existía previamente. Es un poco intuitivo, pero es así.Dado que se debe permitir que falle e inserte un valor predeterminado, el operador no se puede usar en una
constinstancia del contenedor.http://en.cppreference.com/w/cpp/container/map/operator_at
fuente
std::setno tieneoperator[].std::vectortiene un operador de lectura[]que esconst.mapdebería hacer lo mismo.Ahora que con C ++ 11 puede tener una versión más limpia usando at ()
void MyClass::MyFunction( int x ) const { std::cout << m_map.at(x) << std::endl; }fuente
maptiene const y no constat()s, ¿por qué no lo mismo también paraoperator[]? con la versión const no insertando nada sino tirando? (O devolver un opcional, cuando std :: opcional lo convierte en el estándar)atviene en dos sabores es porque hace areturn *this;, y la única diferencia entre las sobrecargas es el carácterconstde la referencia devuelta. Los efectos reales de ambosats son exactamente los mismos (es decir, sin efecto).Nota para nuevos lectores.
La pregunta original era sobre contenedores STL (no específicamente sobre std :: map)
Cabe señalar que existe una versión constante de operator [] en la mayoría de los contenedores.
Es solo que std :: map y std :: set no tienen una versión constante y esto es el resultado de la estructura subyacente que los implementa.
Desde std :: vector
reference operator[](size_type n) const_reference operator[](size_type n) constAdemás, para su segundo ejemplo, debe verificar si no se encuentra el elemento.
void MyClass::MyFunction( int x ) const { MyMap iter = m_map.find(x); if (iter != m_map.end()) { std::cout << iter->second << std::endl } }fuente
std::setno tieneoperator[]nada.Dado que el operador [] podría insertar un nuevo elemento en el contenedor, no es posible que sea una función miembro constante. Tenga en cuenta que la definición de operador [] es extremadamente simple: m [k] es equivalente a (* ((m.insert (value_type (k, data_type ()))). First)). Second. Estrictamente hablando, esta función de miembro es innecesaria: existe solo por conveniencia
fuente
Un operador de índice solo debe ser constante para un contenedor de solo lectura (que realmente no existe en STL per se).
Los operadores de índice no solo se utilizan para observar valores.
fuente
consty otra noconst, como por ejemplostd::vector.Si declara que su variable miembro std :: map es mutable
mutable std::map<...> m_map;puede usar las funciones miembro no constante de std :: map dentro de sus funciones miembro constante.
fuente
mutablese puede utilizar para miembros comostd::mutex, cachés y ayudantes de depuración. Si el mapa se va a utilizar como caché para acelerar unaconstfunción "captadora" muy cara , entoncesmutablees aceptable. Debe tener cuidado, pero no es una idea terrible por sí sola.