为什么find_if在我的程序中不起作用

Why find_if not working in my program?

本文关键字:程序 不起作用 我的 find if 为什么      更新时间:2023-10-16

我有一个简单的程序,它调用std::find_if,我想我已经将前两个参数作为迭代器传递,将第三个参数作为预测传递,但代码仍然无法编译,有什么想法吗?

#include <string>
#include <cctype>
#include <algorithm>
bool notspace(char ch);
bool space(char ch);
int main()  {
    typedef std::string::const_iterator iter;
    iter i;
    std::string s = "ab c";
    i = std::find_if(i, s.end(),space);
    return 0;
}
bool space(char ch)  {
    return std::isspace(ch);
}

错误消息:

q-isspace.cpp: In function ‘int main()’:
q-isspace.cpp:12:38: error: no matching function for call to ‘find_if(iter&, std::__cxx11::basic_string<char>::iterator, bool (&)(char))’
     i = std::find_if(i, s.end(),space);
                                      ^
In file included from /usr/include/c++/5/algorithm:62:0,
                 from q-isspace.cpp:3:
/usr/include/c++/5/bits/stl_algo.h:3806:5: note: candidate: template<class _IIter, class _Predicate> _IIter std::find_if(_IIter, _IIter, _Predicate)
     find_if(_InputIterator __first, _InputIterator __last,
     ^
/usr/include/c++/5/bits/stl_algo.h:3806:5: note:   template argument deduction/substitution failed:
q-isspace.cpp:12:38: note:   deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >’ and ‘__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >’)
     i = std::find_if(i, s.end(),space);

将类型为std::string::const_iterator(也未初始化(的i作为第一个参数传递给std::find_if。然后传递s.end(),返回一个std::string::iterator。这两个迭代器的类型不同,而std::find_if希望它们的类型相同。

正确的经验法则是将呼叫配对到begin()end()

#include <string>
#include <cctype>
#include <algorithm>
bool notspace(char ch);
bool space(char ch);
int main()  {
    typedef std::string::const_iterator iter;
    iter i,j;
    std::string s = "ab c";
    i = std::find_if(s.begin(), s.end(),notspace);
    j = std::find_if(s.begin(), s.end(),space);
    return 0;
}
bool space(char ch)  {
    return std::isspace(ch);
}
bool notspace(char ch)   {
    return !std::isspace(ch);
}
int main()  {
    typedef std::string::const_iterator iter;
    iter i,j;
    std::string s = "ab c";
    i = std::find_if(i, s.end(),notspace);
    j = std::find_if(i, s.end(),space);
    return 0;
}

您没有初始化i变量,因此它没有指向任何内容。这意味着[i, s.end())不构成有效范围,因此您对find_if()的调用将无法正常工作。

试试这个:

i = std::find_if(s.begin(), s.end(), notspace);
iter i,j;
std::string s = "ab c";
i = std::find_if(i, s.end(),notspace);

这将调用std::find_if,并将默认初始化的迭代器作为其第一个参数。该迭代器与s中的任何迭代器都没有关系,因此结果将是无意义的。将呼叫更改为

`std::find_if(s.begin(), s.end(), notspace);

并在另一个调用中进行类似的更改。

如果你想知道编译错误的原因,那是因为std::find_if只有一个模板参数。s.end()是一个普通迭代器,而i是一个const_iterator,它们不匹配。然后是i未初始化的问题,这将导致运行时错误。只需使用s.begin():

i = std::find_if(s.begin(), s.end(),space);

如果您希望能够通过i更改内容,您应该使其成为一个正常的迭代器:

typedef std::string::iterator iter;

i变量未初始化。更优雅的编码方式是使用lambda函数,如下所示。

    #include <string>
    #include <cctype>
    #include <algorithm>
    int main()  {
        typedef std::string::const_iterator iter;
        iter i,j;
        std::string s = "ab c";
        i = std::find_if(s.begin(), s.end(),[](char ch) { return std::isspace(ch); } );
        j = std::find_if(s.begin(), s.end(),[](char ch) { return !std::isspace(ch); } );
        return 0;
     }