Есть ли в qt что-то вроде find_if из STL?

Представьте, что у меня есть такая структура:

typedef struct
{
    foo *fara;
    int id;
} fooToIDWrapper_t;

и QLinkedList<fooToIDWrapper_t *> FooWrapper; вот так,

Теперь я хочу получить итератор, в котором списки fooToIDWrapper_t-node соответствуют определенному идентификатору.

с помощью STL std:find_if() я мог бы добиться этого, выполнив (просто пример кода для демонстрации, не проверенный на компилируемость):

vector<fooToIDWrapper_t> bar;

auto pred = [ID](const fooToIDWrapper& item) {
    return item.id == ID;
};

std::find_if(std::begin(bar), std::end(bar), pred) != std::end(bar);

Существует ли аналогичный алгоритм в qt? и если не так, как я предполагаю, каким образом я мог бы добиться этого в qt?


person dhein    schedule 29.06.2016    source источник
comment
Qt не поддерживает стандартную библиотеку?   -  person NathanOliver    schedule 29.06.2016
comment
@NathanOliver: я должен добавить, что я полагаюсь на итератор. И должен признать, что понятия не имею, как это смешивать.   -  person dhein    schedule 29.06.2016
comment
Нет, в нем нет: doc.qt.io/qt-5/qtalgorithms. html (см. Рекомендации по переносу).   -  person Gluttton    schedule 29.06.2016
comment
std::find_if использует итераторы. Вы должны иметь возможность вставить этот код и изменить bar на любое имя связанного списка, и он должен работать.   -  person NathanOliver    schedule 29.06.2016
comment
Это было бы прекрасно. я посмотрю   -  person dhein    schedule 29.06.2016


Ответы (2)


Вы можете использовать QLinkedList в find_if! Именно поэтому QLinkedList предоставляет cbegin и cend:

find_if(cbegin(bar), cend(bar), [ID](const fooToIDWrapper& item) { return item.id == ID;} ) != cend(bar)

Также примите во внимание: any_of что кажется более разумным, учитывая, что вы мы просто сравним полученный итератор с cend(bar):

any_of(cbegin(bar), cend(bar), [ID](const fooToIDWrapper& item) { return item.id == ID;})

ИЗМЕНИТЬ:

Вы по-прежнему хотите использовать итераторы const, поскольку не пытаетесь изменить контейнер. Вам просто нужно использовать constBegin и constEnd перед Qt5. Итак, вы можете сделать это:

any_of(bar.constBegin(), bar.constEnd(), [ID](const fooToIDWrapper& item) { return item.id == ID;})

Если вы чувствуете постоянную потребность в использовании аксессоров iterator библиотек с Qt4, вы не сможете использовать const итераторы:

any_of(begin(bar), end(bar), [ID](const fooToIDWrapper& item) { return item.id == ID;})
person Jonathan Mee    schedule 29.06.2016
comment
это было бы отличным решением! Но, к сожалению, я ограничен qt 4.8 - person dhein; 29.06.2016
comment
@Zaibis Не бойтесь, Qt4 также предоставил итераторы const, просто у функций доступа были нестандартные имена. Я отредактировал свой ответ, чтобы отразить это. - person Jonathan Mee; 29.06.2016

В этом случае нет причин не использовать std::find_if. STL алгоритмы являются кроссплатформенными и совместимы с Qt контейнерами. В QtAlgorithm библиотеке нет подобного алгоритма

QLinkedList<fooToIDWrapper_t *> bar;

auto pred = [ID](const fooToIDWrapper& item) {
    return item.id == ID;
};

std::find_if(bar.begin(), bar.end(), pred) != std::end(bar);
person Inline    schedule 29.06.2016