2016-10-25 3 views
4

나는 간단한 프로그래밍을 가지고 std::find_if을 호출한다. 나는 처음 두 개의 인수를 반복자로 전달하고 세 번째는 예측으로 전달한다고 생각하지만, 코드는 여전히 컴파일되지 않는다.내 프로그램에서 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); 
+3

'i'와 'j'는 초기화되지 않습니다. 그렇다면'find_if'는 어디에서 시작해야할까요? – UnholySheep

답변

8

의 첫 번째 매개 변수로 std::string::const_iterator (및 초기화되지 않은) 유형 인 i을 전달합니다. 그런 다음 s.end()을 전달하면 std::string::iterator이 반환됩니다. 두 개의 반복자는 서로 다른 유형이며, std::find_if은 두 유형의 반복자를 기대합니다. 당신은 왜 컴파일 오류를 알고 싶다면

엄지 손가락의 정확한 규칙은 std::find_if는 1 개 템플릿 매개 변수를 가지고 있기 때문에 그것의, 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); 
} 
+0

만약 하나가'const_iterator'이고 다른 하나는'iterator'입니까? – buzhidao

+0

@buzhidao, 예. 템플릿 함수 유형 공제는 매우 구체적입니다. 'std :: find_if'는 오직 하나의'InputIterator' 타입만을 명명합니다. – StoryTeller

+0

'std :: string' 전에'const'를 사용했을 때, 컴파일 에러가 없을 것입니다. – buzhidao

5
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 변수를 initalising하지 않는, 그래서 아무것도 가리키는되지 않습니다. 즉, [i, s.end())은 유효한 범위를 구성하지 않으므로 find_if()에 대한 호출이 올바르게 작동하지 않습니다.

대신을 시도

i = std::find_if(s.begin(), s.end(), notspace); 
+0

그러면 컴파일러 오류가 발생하지 않습니다. – juanchopanza

+0

@juanchopanza'i '는'const_iterator','s.end()'는'iterator', 추론 실패? –

+0

예, 그게 전부입니다. – juanchopanza

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

이 그 첫 번째 인수로 기본 초기화 반복자와 std::find_if를 호출합니다. 이 반복자는 어떤 반복자와도 관계가 없으므로 결과는 말도 안됩니다. 전화를

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

으로 변경하고 다른 전화에서 유사한 변경을하십시오.

+1

필자는 컴파일러 오류가 다른 유형의 이터레이터 때문인 것으로 확신합니다. – juanchopanza

+1

@juanchopanza - 예, 아마도 typedef를'typedef std :: string :: iterator iter; '로 바꾸어 리턴 타입이 일치 할 필요가 있습니다. –

3

에 전화를 페어링하는 것입니다. s.end()은 일반적인 반복자이며 iconst_iterator이고 일치하지 않습니다. 그리고 나서 i이 초기화되지 않아서 런타임 오류가 발생할 수 있습니다. 그냥 s.begin()를 사용

typedef std::string::iterator iter; 
1

i 변수가 초기화되지 않습니다

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

당신이 i을 통해 내용을 변경할 수 있도록하려면, 당신은 그것을 정상적인 반복자를해야한다. 좀 더 우아한 방법은 아래와 같이 람다 함수를 사용하는 것입니다.

#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; 
    } 
관련 문제