STL алгоритмы и const_iterators
Вопрос
Сегодня я написал небольшой предикат для поиска подходящих символов в контейнере.
Но я столкнулся с проблемой: я хочу использовать этот предикат в вызове std::find_if
внутри const-метода класса для поиска в контейнере, который является членом этого класса.
Но я только что заметил, что ни std::find
, ни const_iterators
не могут работать с <=>!
Я проверил некоторые ссылки на C ++, и, похоже, нет версий <=> или <=>, которые принимают / возвращают <=>. Я просто не могу понять, почему, поскольку из того, что я видел, эти алгоритмы не могли изменить объект, на который ссылается итератор.
Вот как описано <=> в реализации SGI:
Возвращает первый итератор i в диапазон [первый, последний) такой, что * i == значение. Возвращает последний, если нет такого итератор существует.
Решение
std::find
и std::find_if
могут определенно работать с *::const_iterator
для данного контейнера. Вы случайно не смотрите на сигнатуры этих функций и не понимаете их?
template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);
Обратите внимание, что InputIterator
здесь это просто имя параметра типа шаблона, и любой const_iterator
будет соответствовать требованиям для него.
Или, возможно, вы путаете const
(то есть итератор, ссылающийся на значение const) с <=> итератором (то есть итератором, который сам по себе <=>)?
Другие советы
std::find
и std::find_if
оба принимают тип итератора в качестве параметра шаблона, поэтому они наверняка могут работать с const_iterators
. Просто для быстрого примера:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> x;
std::fill_n(std::back_inserter(x), 20, 2);
x.push_back(3);
std::vector<int>::const_iterator b = x.begin();
std::vector<int>::const_iterator e = x.end();
std::vector<int>::const_iterator p = std::find(b, e, 3);
std::cout << *p << " found at position: " << std::distance(b, p) << "\n";
return 0;
}
Это должно быть принято любым правильно работающим компилятором C ++ и привести к следующим результатам:
3 найдено в позиции: 20
У меня только что была такая же проблема. У меня была функция-член, которая вызывала find_if
для вектора-члена, и компилятор выдал мне ошибку, когда я попытался создать функцию-член const
. Оказалось, что это потому, что я присваивал возвращаемое значение iterator
для const_iterator
вместо <=>. Это заставило компилятор предположить, что параметры <=> также должны быть <=> вместо <=>, чего он не мог получить из вектора-члена <=>.
Если вы случайно оказались здесь по той же причине, что и я:
error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’
Это не имеет ничего общего с const_iterator
с. Вы, наверное, просто забыли #include <algorithm>
: -)
У меня только что была проблема с этим кодом:
std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');
Ошибка: " нет соответствующей перегрузки для std :: find ".
Нужно было исправить с помощью cend (). Это сбивает с толку, что cbegin () не требуется, я не уверен, почему это преобразование в порядке (неявно), а не для end () в качестве параметра функции.