2016-08-12 3 views
1

Есть ли какая-то особая причина, почему std::vector не имеет функции-члена find? Вместо этого вы должны позвонить std::find#include <algorithm>).Нет найти участника в std :: vector

Причина, по которой я прошу, состоит в том, что я считаю, что было бы хорошо, если бы можно было изменить класс контейнера в какой-то части реализации без необходимости изменять код везде, где доступен доступ к контейнеру. Скажем, я заменяю std::vector, где реализация использует std::find с std::map. Затем мне также необходимо заменить вызов std::find вызовом участнику find, если я не хочу поддерживать линейную сложность std::find. Почему бы просто не иметь члена find для всех классов контейнеров, который находит элемент с любым алгоритмом, наиболее подходящим для каждого контейнера?

+3

Я не вижу проблемы. 'std :: find' является общим и работает для всех объектов/конструкций, которые обеспечивают итератор, придерживающийся концепции« InputIterator ». –

+1

Поскольку 'std :: map :: find' ищет ключ, а' std :: find' ищет пару 'key, value', поэтому это два разных алгоритма. – Holt

+0

Вопрос не в том, почему существует 'std :: find'. Поэтому нет функции-члена 'find'. Очевидно, что 'std :: find' не следует удалять ... – Martin

ответ

5

Концептуально std::find требуется только два InputIterator s для работы, а не std::vector. Таким образом, одна реализация работает для всех контейнеров, включая контейнеры STL, и стандартные массивы, и все, что может предоставить InputIterator, включая, например, istream_iterator() - приятно!

Таким образом, вместо предоставления одного метода find() для каждого контейнера (и учитывать, что для некоторых он может быть невозможен, как стандартные массивы), для всех предоставляется одна общая функция find(). Это, скорее всего, сделает ваш код более устойчивым к изменению, чем добавление метода find() для каждого контейнера, поскольку он обеспечивает согласованный интерфейс для поиска в любой коллекции: поток ввода из консоли, сети и т. Д. Или просто базовый массив. Это важный аспект стандартного дизайна STL : вы можете искать элементы в любой коллекции , определяемой двумя InputIterator s.

Недостатком, как вы заметили, является то, что в некоторых случаях более высокая производительность может быть достигнута с использованием собственного метода контейнера, который может сделать специальные предположения для повышения производительности (аналогично для list::remove, unorderd_map::remove/find() и т. Д.). По этой причине контейнеры могут предоставить (и это хорошо известная конструктивная особенность STL) способ специально для повышения производительности: например, std::unordered_map не требует, чтобы один итератор просматривал всю карту, чтобы найти элемент.

Таким образом, поскольку общий std::find эффективно работает для вектора, нет необходимости предоставлять функцию-член, поскольку это может привести к еще менее портативному дизайну.

для всех вещей, связанных с СТЛ см The C++ Standard Library - A Tutorial and Reference, 2nd Edition

0

std :: find - общее решение. некоторые классы нуждаются в какой-то специализации этой функции, поэтому они имеют их локально (так как я помню, что Мейерс сказал, что если класс имеет свой собственный член функции, то вы должны использовать его, а не глобально)