Страницы

Поиск по вопросам

среда, 29 января 2020 г.

третий параметр алгоритма find

#cpp


Используя метод find, легко найти есть ли заданное значение в контейнере, или нет:

std::vector vec;
std::vector::iterator itr = find(vec.begin() ,vec.end(), int val);
if(...)


и так далее;

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

class ClassName {
public:
int x;
std::string y;
};


std::string foo = "bar";
std::vector vec1;
std::vector::iterator itr = find( vec1.begin(), vec1.end(), ??? )


Что нужно написать вместо знаков вопроса, чтобы найти такой указатель, который указывает
на объект, поле std::string y которого равно строке foo ?  Если это невозможно с алгоритмом
find, то какие альтернативы?
    


Ответы

Ответ 1



Используйте find_if, она принимает предикат. std::string foo = "bar"; std::vector vec1; auto itr = std::find_if(begin(vec1), end(vec1), [&](ClassName* el){ return el->y == foo; });

Ответ 2



Если вам необходимо сравнить 2 объекта структуры/класса (а find именно этим и занимается, т.е. сравнивает на равенство), то объект должен реализовывать bool operator ==. Для указателей же, @Abyx указал способ решения проблемы (да и не только для указателей). P.S. Если же вы захотите использовать объекты данной структуры/класса в упорядоченных ассоциативных контейнерах (std::map и std::set) в качестве ключа, то структура/класс обязана реализовывать bool operator <, а остальные операторы сравнения могут быть выражены через него, а в неупорядоченных ассоциативных контейнерах необходимо реализовать bool operator == и специализацию std::hash.

Комментариев нет:

Отправить комментарий