найти внутри класса, если элемент существует в векторе пар

Я пишу в C ++. У меня есть проект с таким количеством файлов. У меня есть вектор пар с именем list следующим образом:

std::vector< std::pair< structure1, double> > list;

и я хочу проверить, если для конкретного двойного значения z существует элемент: el в списке таких, что: el.second == z

Я хочу использовать find_if

Для этого я реализовал метод: Scheduled это принимает два аргумента: первый — это элемент, подобный тем, которые хранятся в списке, второй — конкретное значение, которое нужно искать.
Я пробовал несколько способов, но я всегда получаю ошибку
1-й способ:

 bool classA::Scheduled(std::pair< structure1,double > const el, double const t )
{
return el.second==t;

}

внутри другого метода, но все еще в том же классе: classA

auto Scheduled1 = std::bind(&classA::Scheduled,this,_1,z);bool call=std::find_if(list.begin(),list.end(),Scheduled1)=!list.end();

Это решение дает следующую ошибку:

 error: ‘Scheduled1’ does not name a type

2-й способ:
напрямую используя лямбду

bool call = std::find_if(list.begin(),list.end(),[this](std::pair<struct1,double> const& el){return el.second==z;})!=list.end();

z является переменной-членом класса A
Этот второй способ кодирования приводит к этой ошибке:

error: no matching function for call to

‘Find_if (std :: vector> :: iterator, std :: vector> :: iterator, classA :: method1 (int) :: __ lambda0)’

0

Решение

Там нет необходимости смешивать bind, bind1st а также mem_fun сделать это (последние два устарели в C ++ 11); просто используйте лямбду

bool call = std::find_if(list.begin(), list.end(),
[this](std::pair< strucure1,double > const& el) {
return el.second == z;
}) != list.end();

Или если вы хотите позвонить Scheduled

bool call = std::find_if(list.begin(), list.end(),
[this](std::pair< strucure1,double > const& el) {
return Scheduled(el, z);
}) != list.end();

Если вы должны использовать bind

bool call = std::find_if(list.begin(), list.end(),
std::bind(&classA::Scheduled, this, _1, z)) != list.end();

В любом случае, вы можете изменить Scheduled быть static функция-член, так как ей не нужен доступ к каким-либо нестатическим элементам, в этом случае bind вариант становится

bool call = std::find_if(list.begin(), list.end(),
std::bind(&classA::Scheduled, _1, z)) != list.end();

Также, Scheduled вероятно, следует взять std::pair аргумент const& чтобы избежать ненужных копий.

Другой вариант заключается в использовании any_of вместо find_ifчто позволяет избежать необходимости сравнивать результат с конечным интегратором

bool call = std::any_of(list.begin(), list.end(),
<insert lambda or bind expression>);

Вот объяснение того, что не так с вашей попыткой.

auto Scheduled1=std::bind(Scheduled, _1, z);

Scheduled является нестатической функцией-членом, что означает, что она принимает неявный первый аргумент, указатель на экземпляр, на который она должна быть вызвана, т.е. this указатель. Кроме того, синтаксис для создания указателя на функцию-член &ClassName::MemberFunctionName, Таким образом, приведенная выше строка должна быть

auto Scheduled1=std::bind(&classA::Scheduled, this, _1, z);

bind возвращает объект функции неопределенного типа, но вы используете этот объект, как если бы он был функцией-членом (mem_fun(&classA::Scheduled1)) что явно неверно. Просто передавая выше Scheduled1 объект в качестве третьего аргумента find_if в вашем примере должно работать.

4

Другие решения

Как упомянул @Praetorian, вы могли бы использовать лямбды. Однако связыватели позволяют использовать существующие функции предикатов «из коробки», хотя и иногда более читабельны (тот факт, что новый std :: bind автоматически связывает функцию-член с экземпляром, позволяет использовать открытый интерфейс типа из коробки). Я добавил пример, аналогичный вашему (который компилируется), в котором я объясню некоторые вещи (см. Комментарии к коду):

#include <iostream>
#include <vector>
#include <utility>
#include <functional>
#include <algorithm>

// Replaces your structure...
struct Xs{};// typedef so that we can alias the ugly thing...
typedef std::vector<std::pair<Xs, double>> XDoubleVector;

// --- From your code, I've just named it A for brevity....
struct A
{
bool Scheduled(std::pair<Xs,double> const el, double const t )
{
return el.second==t;
}
};int main() {

using namespace std::placeholders;
//Instantiate it.... replaced your list.
XDoubleVector doubleVect;
//--- and add some elements....

//We need to instantiate A, in order to invoke
// a member function...
A a;

// Returns true if found...
return std::find_if(
doubleVect.begin(),
doubleVect.end(),
//Notes:
//- Scheduled is a member function of A
//- For that reason, we need to pass an instance of
//   A to binder (almost seen as first bound).
//- _1 indicates that the first parameter to Scheduled will be
//   passed in by algorithm
//- We've hardcoded the second parameter (it is therefore
//   bound early).
std::bind(&A::Scheduled, a, _1, 20.9)) != doubleVect.end();

}

С уважением, Вернер

0

По вопросам рекламы [email protected]