Pregunta ¿Por qué no está el operador [] const para los mapas STL?


Ejemplo inspirado, por el bien de la pregunta:

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map[x] << std::endl
}

Esto no compilará, ya que el operador [] no es const.

Esto es desafortunado, ya que la sintaxis [] se ve 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 const?


74
2017-09-25 00:45


origen


Respuestas:


por std::map, operator[] insertará el valor del índice en el contenedor si no existía anteriormente. Es un poco intuitivo, pero así son las cosas.

Como se debe permitir que falle e inserte un valor predeterminado, el operador no se puede usar en un const instancia del contenedor.

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


77
2017-09-25 01:05



Ahora que con C ++ 11 puedes tener una versión más limpia usando a()

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map.at(x) << std::endl;
}

43
2017-08-09 12:28



Nota para nuevos lectores.
La pregunta original era sobre contenedores STL (no específicamente sobre el estándar :: mapa)

Cabe señalar que hay una versión constante del operador [] en la mayoría de los contenedores.
Es solo que std :: map y std :: set no tienen una versión const y esto es el resultado de la estructura subyacente que los implementa.

De std :: vector

reference       operator[](size_type n) 
const_reference operator[](size_type n) const 

También 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
    }
}

26
2017-09-25 00:53



Debido a que el operador [] podría insertar un nuevo elemento en el contenedor, no puede ser una función miembro. 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 miembro es innecesaria: existe solo por conveniencia


3
2017-09-25 12:35



Un operador de índice solo debería ser const para un contenedor de solo lectura (que realmente no existe en STL per se).

Los operadores de índice no solo se usan para ver valores.


0
2017-09-25 00:53



Si declara que su variable de miembro std :: map es mutable

mutable std::map<...> m_map;

puede usar las funciones miembro non-const de std :: map dentro de sus funciones miembro integrantes.


0
2017-09-25 01:18