C ++ STL:字符串迭代器出现问题

时间:2010-05-27 22:59:22

标签: c++ stl iterator

我正在制作一个简单的命令行Hangman游戏。

void Hangman::printStatus()
{
    cout << "Lives remaining: " << livesRemaining << endl;
    cout << getFormattedAnswer() << endl;
}

string Hangman::getFormattedAnswer()
{
    return getFormattedAnswerFrom(correctAnswer.begin(), correctAnswer.end());
}

string Hangman::getFormattedAnswerFrom(string::const_iterator begin, string::const_iterator end)
{
    return begin == end? "" : displayChar(*begin) + getFormattedAnswerFrom(++begin, end);
}

char Hangman::displayChar(const char c)
{
    return c;
}

(最后,我会更改此内容,以便displayChar()显示-或字符(如果用户猜对了),但为了简单起见,我现在只返回所有内容。)

当我从VS 2010构建并运行它时,我得到一个弹出框:

  

Debug Assertion失败!

     

xstring Line:78

     

表达式:不是字符串迭代器   提领

我做错了什么?

3 个答案:

答案 0 :(得分:8)

问题出在评估中:

displayChar(*begin) + getFormattedAnswerFrom(++begin, end)

在执行此语句时,很明显您的编译器首先递增begin,返回“下一个”begin以用作getFormattedAnswerFrom的第一个参数,并且然后begin的参数解除引用displayChar

如果begin落后于end,那么begin != end将会运行displayChar(*begin) + getFormattedAnswerFrom(++begin, end)。您的编译器递增begin,现在begin == endbegin的取消引用无效。

另请参阅:Order of evaluation in C++ function parameters

答案 1 :(得分:0)

如果correctAnswer为空,则correctAnswer.begin()将与correctAnswer.end()相同,且不可取消引用。

答案 2 :(得分:0)

对我来说似乎很好。但是,请记住任何堆或堆栈损坏都可能产生此错误。你需要抓住堆栈跟踪并查看correctAnswer,并确保它和有问题的Hangman实例都是有效的对象。

另外,我只是对这里的功能感到担心。他们似乎很奇怪。为什么不用std :: for_each替换?

编辑@评论:
如果您有C ++ 0x,则可以执行

std::for_each(correctAnswer.begin(), correctAnswer.end(), [this](const char& ref) {
    std::cout << this->displayChar(ref);
});

否则,你将不得不做一些看起来像这样的事情:

struct helper {
    Hangman* ptr;
    void operator()(const char& ref) {
        std::cout << ptr->displayChar(ref);
    }
};
helper Helper;
Helper.ptr = this;
std::for_each(correctAnswer.begin(), correctAnswer.end(), Helper);