shiraz
shiraz

Reputation: 1218

= not defined for std::search when using const string&

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

Answers (3)

StevieG
StevieG

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

Alan Stokes
Alan Stokes

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

Mike Seymour
Mike Seymour

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

Related Questions