Другой общий случай, когда можно получить это исключение, включает в себя насмешливые классы во время модульного тестирования. Независимо от используемой насмешливой структуры, вы должны убедиться, что все соответствующие уровни иерархии классов должным образом высмеиваются. В частности, все свойства HttpContext
, на которые ссылается тестируемый код, должны быть изделены.
См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.
Для std::map
, operator[]
вставляет значение индекса в контейнер, если оно ранее не существовало. Это немного неинтуитивно, но так оно и есть.
Поскольку он должен быть допущен к ошибке и вставить значение по умолчанию, оператор не может использоваться в экземпляре const
контейнера.
Если вы объявляете, что ваша переменная-член std :: map является изменяемой
mutable std::map<...> m_map;
, вы можете использовать не-const-функции-члены std :: map внутри ваших функций-членов const.
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
}
}
Теперь, когда с C ++ 11 вы можете иметь более чистую версию, используя at ()
void MyClass::MyFunction( int x ) const
{
std::cout << m_map.at(x) << std::endl;
}
map
имеют const и non-const at()
s - почему не то же самое для operator[]
? с версией const, не вставляющей ничего, а скорее бросая? (Или возврат необязательного значения, когда std :: optional делает его стандартным)
– einpoklum
10 December 2015 в 17:19
Оператор индекса должен быть только const для контейнера только для чтения (который действительно не существует в STL как таковой).
Операторы индексов используются не только для просмотра значений.
const
, другой не const
- как, например, std::vector
делает.
– Pavel Minaev
25 September 2009 в 02:49
Так как оператор [] может вставить новый элемент в контейнер, он не может быть функцией-константой. Заметим, что определение оператора [] предельно просто: m [k] эквивалентно (* ((m.insert (value_type (k, data_type ()))).) Сначала.). Строго говоря, эта функция-член не нужна: она существует только для удобства
std::set
не имеетoperator[]
. – avakar 25 September 2009 в 07:20