Reputation: 1218
I have the following code, which works fine, however when I change the iter getB(string& s , string& tag);
function definition to iter getB(const string& s , const string& tag);
I get the error pasted at the end. I believe the =
operator is not defined because with this new function definition, if I don't assign the result of search
to i
the program compiles, though later resulting in a segmentation fault, which I believe is expected. Can someone explain to me why I can't assign the result of search
when the function definition contains const
keywords. Thank you.
the code:
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
typedef string::iterator iter;
iter getB(string& s , string& tag);
int main (){
string line = "hello, how are you?";
string tag = "how";
iter i = getB(line,tag);
for(i ; i!=line.end(); i++){
cout << *i ;
}
cout << endl;
return 0;
}
iter getB(string& s , string& tag)
{
iter i;
i = search(s.begin() , s.end() , tag.begin() , tag.end());
return i;
}
~
~
the error message with the altered function definition:
test1.cpp: In function ‘iter getB(const std::string&, const std::string&)’:
test1.cpp:24: error: no match for ‘operator=’ in ‘i = std::search [with _ForwardIterator1 = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _ForwardIterator2 = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >](((const std::string*)s)->std::basic_string<_CharT, _Traits, _Alloc>::begin [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](), ((const std::string*)s)->std::basic_string<_CharT, _Traits, _Alloc>::end [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](), ((const std::string*)tag)->std::basic_string<_CharT, _Traits, _Alloc>::begin [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](), ((const std::string*)tag)->std::basic_string<_CharT, _Traits, _Alloc>::end [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]())’
/usr/include/c++/4.2.1/bits/stl_iterator.h:637: note: candidates are: __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >& __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator=(const __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)
Upvotes: 1
Views: 975
Reputation: 8709
if you pass in a const iterator to std::search, then the return value is also a const iterator (it will be of the same type as the first iterator passed in)
change this:
typedef string::iterator iter;
to this:
typedef string::const_iterator iter;
Upvotes: 1
Reputation: 18974
For a const string
, begin()
and end()
return std::string::const_iterator
not std::string::iterator
. You can convert an iterator
to a const_iterator
, but not vice versa.
The quick solution would be to change your typedef:
typedef string::const_iterator iter;
Upvotes: 4
Reputation: 254631
If s
is a const string &
, then s.begin()
, and hence the return type of search
, is string::const_iterator
. This is not convertible to string::iterator
, which is the type of i
.
This is as it should be, since otherwise that conversion would break const
-correctness by allowing you to modify the string. You should change the type of i
to string::const_iterator
, or perhaps auto
if you're using C++11.
Upvotes: 2