C++ STL:迭代器问题

Nic*_*ner 0 c++ syntax type-safety

我有一个初学者问题:

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);
}
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?为什么不str.begin()检查类型string::iterator

更新:更好的版本:

bool BrittlePalindrome::_isPalindrome(string::const_iterator begin, string::const_iterator end)
{
    return begin >= end || *begin == *(end - 1) && _isPalindrome(++begin, --end);
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*off 5

str.begin()是非const,而参数str const.

您可以更改迭代器接受方法以接受const_iterators,也可以更改字符串接受方法以接受非const string.

或者你可以抛弃它str的常数,但这将是一个专利Bad Idea TM.

(我还会在迭代器接受方法上加上你的return语句的括号,以使你的意图更清晰,但这既不在这里也不在那里.)


CB *_*ley 5

假设您在第一个函数之前声明了第二个函数,主要问题是您是通过const引用传递字符串.

这意味着,只有重载begin()end()你有机会获得其是返回常量版本std::string::const_iterator,而不是std::string::iterator.

迭代器的约定是结束迭代器指向超出范围末尾的一个并且不是可解除引用的 - 当然如果你str.end()作为end参数传递.这意味着*begin == *end无效,您需要先减少一次结束.对于具有奇数个元素的范围,您也会遇到问题.通过执行++begin并且--end不进一步检查,您的迭代器可能会在递归中交叉而不是触发begin == end条件.

另请注意,为了获得最大的可移植性,全局标识符不应以下划线开头.