Я пишу в 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)’
Там нет необходимости смешивать 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
в вашем примере должно работать.
Как упомянул @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();
}
С уважением, Вернер