Операторы индекса const контейнеров STL
могут возвращать ссылку на константу, потому что они полностью запрещают вызовы к нему с индексами, которые не существуют в контейнере. Поведение в этом случае не определено. Следовательно, как мудрый выбор дизайна, std::map
даже не обеспечивает перегрузку оператора const subscript.
QMap пытается быть немного более уступчивым, предоставляет перегрузку оператора const subscript в качестве синтаксического сахара, сталкивается с проблемой несуществующих ключей, снова пытается быть более уступчивым и вместо этого возвращает значение, построенное по умолчанию.
Если вы хотите сохранить соглашение STL о возврате по константной ссылке, вам нужно выделить статическое значение и вернуть ссылку на это. Это, однако, противоречило бы гарантиям повторного входа, которые предоставляет QMap
, поэтому единственный вариант — возврат по значению. const
есть просто сахарная глазурь, чтобы предотвратить некоторые глупые ошибки, такие как constmap["foo"]++
, от компиляции.
Тем не менее, возврат по ссылке не всегда самый эффективный способ. Если вы возвращаете фундаментальный тип или, с более агрессивной оптимизацией, когда sizeof(T)<=sizeof(void*)
, возврат по значению часто заставляет компилятор возвращать результат в регистр напрямую, а не косвенно (адрес для результата в регистре) или — не дай бог — на куча.
Другая причина (помимо преждевременной пессимизации) предпочтения передачи по константной ссылке, нарезка, здесь неприменима, поскольку и std::map
, и QMap
основаны на значениях и, следовательно, однородны. Для гетерогенного контейнера вам нужно будет хранить указатели, а указатели — это фундаментальные типы (конечно, за исключением интеллектуальных).
Тем не менее, я почти никогда не использую оператор индекса const в Qt. Да, у него более приятный синтаксис, чем у find()
+*it
, но неизменно вы получите вызовы count()
/contains()
прямо перед оператором индекса const, что означает, что вы выполняете двоичный поиск дважды. . И тогда вы все равно не заметите незначительных различий в производительности возвращаемого значения :)
Тем не менее, для value() const
я согласен с тем, что он должен возвращать ссылку на константу, по умолчанию ссылка на значение по умолчанию передается в качестве второго аргумента, но я думаю, что разработчики Qt посчитали, что это слишком много волшебства.
person
Marc Mutz - mmutz
schedule
15.07.2009