简体   繁体   中英

How can I use predicate function in find_if algorithm?

The predicate function:

bool Schedule::predicateFunc(map<pair<string,int>,pair<string,Array> >::iterator it,string &a)
{
    return (it->first).first == a;
}

Function which I have to use predicate func:

 void Schedule::studentSchedule() {
    string s,c;
    cout<<"Enter the student and course name to create schedule"<<endl;
    cin>>s>>c;
    list<string>::iterator studentLoc;
    map<pair<string,int>,pair<string,Array> >::iterator courseL;
    map<pair<string,int>,pair<string,Array> >::iterator location;

    studentLoc = find(getStudentList().begin(),getStudentList().end(),s);
    location = find_if(getMatchMap().begin(), getMatchMap().end(), predicateFunc(courseL,c) )       
    if(studentLoc != getStudentList().end() && location != getMatchMap().end())
        {
            cout<<"I found it"<<endl;
        }
        else
            cout<<"I cant found it"<<endl;
    }

When I tried to use predicate function in here:

location = find_if(getMatchMap().begin(), getMatchMap().end(), predicateFunc(courseL,c) )  

I am getting an error like this:

In file included from C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algobase.h:71,
                 from C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:61,
                 from C:\Users\Fatih\Desktop\clion\SchoolProject1\Schedule.cpp:4:
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, int>, std::pair<std::__cxx11::basic_string<char>, std::array<int, 6> > > >; _Predicate = bool]':
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:104:42:   required from '_InputIterator std::__find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, int>, std::pair<std::__cxx11::basic_string<char>, std::array<int, 6> > > >; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool>]'
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:161:23:   required from '_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, int>, std::pair<std::__cxx11::basic_string<char>, std::array<int, 6> > > >; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool>]'
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:3930:28:   required from '_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, int>, std::pair<std::__cxx11::basic_string<char>, std::array<int, 6> > > >; _Predicate = bool]'
C:\Users\Fatih\Desktop\clion\SchoolProject1\Schedule.cpp:25:93:   required from here
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h:283:11: error: expression cannot be used as a function
  { return bool(_M_pred(*__it)); }
           ^~~~~~~~~~~~~~~~~~~~

What is the true usage of the predicate funtion in here ?

You are calling your predicate function but you must provide a reference to your predicate function:

location = find_if(getMatchMap().begin(), getMatchMap().end(), predicateFunc);

Also, the signature of your predicate function is not correct. It should take only one argument and this argument is not an iterator, but the value of the collection/iterator. It is probably also a good idea to make it a const-reference.

bool Schedule::predicateFunc(const map<pair<string,int>,pair<string,Array> >::value_type& x);

If you need to provide an argument to your predicate function, you have several options:

  • Do not use a separate predicate function, but a lambda expression.
  • Use std::bind() .
  • Use a function object.

You're probably misunderstanding the concept of Predicate . It must be a function that takes one element of the collection and returns a bool . This function is now called for each element in the range until the first time it returns true (see here ).

In your code, you're calling the predicate instead of passing it to find_if .

Also, the signature of your predicate is wrong: It takes two parameters instead of one. The signature should be

bool Schedule::predicateFunc(const map<pair<string,int>,pair<string,Array> >::value_type& x);

If you want to pass it an additional argument, eg a string to be compared with, you coulddo something like:

bool Schedule::compareName(map<pair<string,int>,pair<string,Array> >::value_type& x,string &a)
{
    return (x.first).first == a;
}

and then in the calling code:

std::string expected_name = "some name";
auto predicate = [&](auto& course) { return compareName(course, expected_name); };
location = find_if(getMatchMap().begin(), getMatchMap().end(), predicate);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM