[英]const_iterator, find_if and bind2nd: no match for call to error
[英]find_if not working with const_iterator
我寫了這個程序:
// splits a sentence into words
#include <iostream>
#include <string>
#include <algorithm>
#include "spacefunc.h"
using std::string;
using std::cout;
using std::endl;
using std::find_if;
int main() {
typedef string::const_iterator iter;
string input = "This is me";
iter i = input.begin();
while (i != input.end()) {
iter j;
i = find_if(i, input.end(), notspace);
j = find_if(i, input.end(), is_space);
cout << string(i, j) << endl;
i = j;
}
return 0;
}
它失敗並出現以下錯誤:
word_splitter.cpp: In function ‘int main()’:
word_splitter.cpp:21:45: error: no matching function for call to ‘find_if(iter&, std::__cxx11::basic_string<char>::iterator, bool (&)(char))’
i = find_if(i, input.end(), notspace);
^
In file included from /usr/include/c++/5/algorithm:62:0,
from word_splitter.cpp:4:
/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:
word_splitter.cpp:21:45: 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 = find_if(i, input.end(), notspace);
^
word_splitter.cpp:22:45: error: no matching function for call to ‘find_if(iter&, std::__cxx11::basic_string<char>::iterator, bool (&)(char))’
j = find_if(i, input.end(), is_space);
^
In file included from /usr/include/c++/5/algorithm:62:0,
from word_splitter.cpp:4:
/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:
word_splitter.cpp:22:45: 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> >’)
j = find_if(i, input.end(), is_space);
如果我將i, j
更改為iterator
類型,則編譯。
我做錯了什么,因為我很確定find_if
接受const_iterator
類型的參數?
編輯如果這是i
作為const_iterator
和input.end()作為iterator
,為什么以下代碼有效? 這來自Accelerated C++
。
vector < string > split(const string & str) {
typedef string::const_iterator iter;
vector < string > ret;
iter i = str.begin();
while (i != str.end()) {
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
iter j = find_if(i, str.end(), space);
// copy the characters in [i, j)
if (i != str.end())
ret.push_back(string(i, j));
i = j;
}
return ret;
}
find_if
接受非const迭代器和const_iterators; 但是,傳遞給它的迭代器必須是相同的類型。 這里的問題是input.end()
返回一個非const迭代器,因為input
不是const對象。 這與const迭代器'i'的類型不同。 要獲得非const對象的const結束迭代器(或對於const對象,但這是一個分心),請使用input.cend()
。
find_if
的簽名如下:
template<class InputIt, class UnaryPredicate> InputIt find_if(InputIt first, InputIt last, UnaryPredicate p);
它希望它的前兩個參數屬於同一類型。 使用find_if(i, input.end(), notspace)
,如果i
是一個string::const_iterator
,它與input.end()
類型不同,它是一個string::iterator
因為input
是非const的。 如果input
是const std::string
,則input.end()
將返回string::const_iterator
在C ++ 11之后,看到一個typedef string::const_iterator iter
並不常見。 使用auto
更常見:
string input = "This is me";
auto i = input.begin();
其他人已經解釋了為什么遇到編譯錯誤。 在我看來,如果你更直接地表達你的“終極”意圖,可以避免未來的錯誤,讓自動類型演繹處理其余的事情。 例如:如果您希望輸入是不可變的,請使用const
將其標記為,並讓auto
處理其余內容。
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
bool is_space(char c) { return std::isspace(c); }
bool is_not_space(char c) { return not is_space(c); }
int main() {
const std::string input{"This is me"};
for (auto it = input.begin(); it != input.end();) {
it = std::find_if(it, input.end(), is_not_space);
auto it_end = std::find_if(it, input.end(), is_space);
std::cout << std::string(it, it_end) << "\n";
it = it_end;
}
}
樣品運行:
$ clang++ example.cpp -std=c++17 -Wall -Wextra
$ ./a.out
This
is
me
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.