【问题标题】:How can I use predicate function in find_if algorithm?如何在 find_if 算法中使用谓词函数?
【发布时间】:2019-12-27 10:55:01
【问题描述】:

谓词函数:

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

我必须使用谓词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;
    }

当我在这里尝试使用谓词函数时:

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

我收到这样的错误:

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)); }
           ^~~~~~~~~~~~~~~~~~~~

这里谓词函数的真正用法是什么?

【问题讨论】:

    标签: c++ predicate


    【解决方案1】:

    您可能误解了Predicate 的概念。它必须是一个函数,它接受集合的一个 元素 并返回 bool。现在为范围内的每个元素调用此函数,直到它第一次返回 true(请参阅 here)。

    在您的代码中,您调用谓词而不是将其传递给find_if

    另外,你的谓词的签名是错误的:它需要两个参数而不是一个。签名应该是

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

    如果你想传递一个额外的参数,例如要比较的字符串,您可以执行以下操作:

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

    然后在调用代码中:

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

    【讨论】:

      【解决方案2】:

      您正在调用您的谓词函数,但您必须提供对您的谓词函数的引用

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

      另外,您的谓词函数的签名不正确。它应该只接受一个参数,并且这个参数不是迭代器,而是集合/迭代器的值。将其设为 const-reference 可能也是一个好主意。

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

      如果您需要为谓词函数提供参数,您有多种选择:

      • 不要使用单独的谓词函数,而是使用 lambda 表达式。
      • 使用std::bind()
      • 使用函数对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 1970-01-01
        相关资源
        最近更新 更多