В чем разница между at и operator [] в методе const? [Дубликат]

Другой общий случай, когда можно получить это исключение, включает в себя насмешливые классы во время модульного тестирования. Независимо от используемой насмешливой структуры, вы должны убедиться, что все соответствующие уровни иерархии классов должным образом высмеиваются. В частности, все свойства HttpContext, на которые ссылается тестируемый код, должны быть изделены.

См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.

74
задан Luc Hermitte 25 September 2009 в 13:42
поделиться

6 ответов

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

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

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

77
ответ дан Morwenn 26 August 2018 в 00:05
поделиться
  • 1
    std::set не имеет operator[]. – avakar 25 September 2009 в 07:20
  • 2
    Ой, это правильно. Ред. – Alan 25 September 2009 в 20:41
  • 3
    Это правильный ответ, но версия const может делать то же самое, что и «at». член. Это бросает std :: out_of_range ... – Jean-Simon Brochu 8 August 2017 в 13:27

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

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

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

0
ответ дан Anthony Cramp 26 August 2018 в 00:05
поделиться
  • 1
    Это ужасная идея. – GManNickG 25 September 2009 в 22:58
  • 2
    Почему это ужасная идея? – Anthony Cramp 2 October 2009 в 14:54
  • 3
    API для вашего класса лежит, если вы это сделаете. Функция утверждает, что она const - это значит, что она не будет изменять какие-либо переменные-члены, но в действительности она может изменять член данных m_map. – Runcible 18 March 2010 в 19:33
  • 4
    mutable может использоваться для таких членов, как std::mutex, кеши и помощники отладки. Если карта должна использоваться в качестве кеша для ускорения очень дорогого const "getter" функции, тогда mutable является приемлемым. Вы должны быть осторожны, но это не страшная идея сама по себе. – Mark Lakata 28 September 2015 в 23:04

Примечание для новых читателей. Первоначальный вопрос касался контейнеров 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
    }
}
26
ответ дан Dan Nissenbaum 26 August 2018 в 00:05
поделиться

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

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map.at(x) << std::endl;
}
43
ответ дан Deqing 26 August 2018 в 00:05
поделиться
  • 1
    Если map имеют const и non-const at() s - почему не то же самое для operator[]? с версией const, не вставляющей ничего, а скорее бросая? (Или возврат необязательного значения, когда std :: optional делает его стандартным) – einpoklum 10 December 2015 в 17:19
  • 2
    @einpoklum Точка корректности const - это, в основном, статическая проверка времени компиляции. Я бы предпочел компилятор жаловаться, чем выбросить исключение, потому что я не использовал объекты const правильно. – Millie Smith 18 April 2016 в 00:07

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

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

0
ответ дан Nick Bedford 26 August 2018 в 00:05
поделиться
  • 1
    Вопрос в том, почему у него нет двух перегруженных версий - один const, другой не const - как, например, std::vector делает. – Pavel Minaev 25 September 2009 в 02:49

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

3
ответ дан Satbir 26 August 2018 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: