Подтвердить что ты не робот

Почему не используется оператор [] const для STL-карт?

Продуманный пример, ради вопроса:

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

Это не будет компилироваться, так как оператор [] не является константой.

Это печально, так как синтаксис [] выглядит очень чистым. Вместо этого я должен сделать что-то вроде этого:

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

Это всегда меня било. Почему оператор [] не const?

4b9b3361

Ответ 1

Для std::map, operator[] будет вставлять значение индекса в контейнер, если оно ранее не существовало. Это немного неинтуитивно, но так оно и есть.

Так как это должно быть разрешено сбой и вставить значение по умолчанию, оператор не может использоваться в экземпляре const контейнера.

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

Ответ 2

Теперь, когда с С++ 11 вы можете иметь более чистую версию, используя at()

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

Ответ 3

Примечание для новых читателей.
Первоначальный вопрос касался контейнеров STL (не конкретно о std:: map)

Следует отметить, что на большинстве контейнеров существует версия const оператора [].
Просто 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
    }
}

Ответ 4

Так как оператор [] может вставить в контейнер новый элемент, он не может быть константной функцией-членом. Заметим, что определение оператора [] предельно просто: m [k] эквивалентно (* ((m.insert(value_type (k, data_type()))).) Сначала.). Строго говоря, эта функция-член не нужна: она существует только для удобства

Ответ 5

Оператор индекса должен быть только const для контейнера только для чтения (который действительно не существует в STL как таковой).

Операторы индексов используются не только для просмотра значений.

Ответ 6

Если вы объявите переменную-член std:: map изменчивой

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

вы можете использовать не-const-функции-члены std:: map внутри ваших функций-членов-членов.