web-dev-qa-db-fra.com

Pourquoi l'opérateur [] n'est-il pas const pour les cartes STL?

Exemple artificiel, pour le bien de la question:

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

Cela ne se compilera pas, car l'opérateur [] est non-const.

C'est malheureux, car la syntaxe [] a l'air très propre. Au lieu de cela, je dois faire quelque chose comme ceci:

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

Cela m'a toujours dérangé. Pourquoi l'opérateur [] est-il non const?

83
Runcible

Pour std::map et std::unordered_map, operator[] insérera la valeur d'index dans le conteneur si elle n'existait pas auparavant. C'est un peu peu intuitif, mais c'est comme ça.

Puisqu'il doit être autorisé à échouer et à insérer une valeur par défaut, l'opérateur ne peut pas être utilisé sur une instance const du conteneur.

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

83
Alan

Maintenant qu'avec C++ 11 vous pouvez avoir une version plus propre en utilisant at ()

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

Remarque pour les nouveaux lecteurs.
La question initiale portait sur les conteneurs STL (pas spécifiquement sur std :: map)

Il convient de noter qu'il existe une version const de l'opérateur [] sur la plupart des conteneurs.
C'est juste que std :: map et std :: set n'ont pas de version const et ceci est le résultat de la structure sous-jacente qui les implémente.

De std :: vector

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

De plus, pour votre deuxième exemple, vous devez vérifier l'absence de recherche de l'élément.

void MyClass::MyFunction( int x ) const
{
    MyMap iter = m_map.find(x);
    if (iter != m_map.end())
    {
        std::cout << iter->second << std::endl
    }
}
28
Martin York

Étant donné que l'opérateur [] peut insérer un nouvel élément dans le conteneur, il ne peut pas être une fonction membre const. Notez que la définition de l'opérateur [] est extrêmement simple: m [k] est équivalent à (* ((m.insert (value_type (k, data_type ()))). First)). Second. A strictement parler, cette fonction membre n'est pas nécessaire: elle n'existe que pour des raisons de commodité

3
Satbir

Un opérateur d'index ne doit être const que pour un conteneur en lecture seule (qui n'existe pas vraiment en STL en soi).

Les opérateurs d'index ne sont pas uniquement utilisés pour examiner les valeurs.

0
Nick Bedford