I’m having a beginner problem:
bool _isPalindrome(const string& str)
{
return _isPalindrome(str.begin(), str.end()); // won't compile
}
bool _isPalindrome(string::iterator begin, string::iterator end)
{
return begin == end || *begin == *end && _isPalindrome(++begin, --end);
}
What am I doing wrong here? Why doesn’t str.begin() get type checked to be a string::iterator?
Update: Better version:
bool BrittlePalindrome::_isPalindrome(string::const_iterator begin, string::const_iterator end)
{
return begin >= end || *begin == *(end - 1) && _isPalindrome(++begin, --end);
}
Assuming that you have a declaration of the second function before the first function, the main issue is that you are passing the strings by
constreference.This means that the only overloads of
begin()andend()that you have access to are the const versions which returnstd::string::const_iteratorand notstd::string::iterator.The convention for iterators is that the end iterator points one beyond the end of a range and is not dereferencable – certainly if you pass
str.end()as theendparameter. This means that*begin == *endis not valid, you need to decrement end once first. You are also going to have an issue with ranges with odd numbers of elements. By doing++beginand--endwith no further checking your iterators may cross over in the recursion rather than triggering thebegin == endcondition.Also note that for maximum portability, global identifiers shouldn’t start with an underscore.