Как получить ссылку на элемент в наборе в C ++? - PullRequest
1 голос
/ 06 марта 2012

Я определил класс Movie.И этот класс имеет

static set<Movie> movies;

У меня также есть статическая функция-член:

static Movie& find_by_title(string);

Я возвращаю ссылку, потому что я хочу изменить фильм, как только я его найду (Я хочу оценить это).Итак, в реализации у меня есть

Movie& Movie::find_by_title(string title) {
  set<Movie>::iterator it;
  for (it = movies.begin(); it != movies.end(); ++it)
    if (it->title == title) return *it;
}

Но он возвращает ошибку, потому что *it имеет тип const Movie (а функция возвращает Movie&).Но тогда как получить этот элемент таким образом, чтобы я мог его изменить?Указатель также будет в порядке, все, что позволит впоследствии изменить элемент.

movies.find(*it) также возвращает итератор в const Movie, поэтому он также не работает, когда я пытаюсь вернуться*(movies.find(*it)).

Ответы [ 2 ]

3 голосов
/ 06 марта 2012

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

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

  • Коллекция потенциально может стать настолько большой, что разница между O (N) и O (log N) будет существенной.
  • Количество поисков того же порядка, что и количество вставок; не так много вставок, что скорость вставки не имеет значения.
  • Элементы вставляются в случайном порядке, а не в порядке.
  • Вставки и поиски чередуются; у нас нет четких фаз вставки и поиска.

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

1 голос
/ 06 марта 2012

Внутренняя работа std::set требует , чтобы элемент не изменялся после его вставки в набор. Если вы попытаетесь изменить его, внутренние структуры будут несовместимы, и будут плохие вещи .

Если ваши элементы данных можно разделить на две части, одну с ключом, который не изменяется, а другую, которую вы будете менять, используйте std::pair<const key,data> для двух частей и поместите их в std::map.

...