C++ C++;STL:字符串迭代器的问题
我正在制作一个简单的命令行刽子手游戏C++ C++;STL:字符串迭代器的问题,c++,stl,iterator,C++,Stl,Iterator,我正在制作一个简单的命令行刽子手游戏 void Hangman::printStatus() { cout << "Lives remaining: " << livesRemaining << endl; cout << getFormattedAnswer() << endl; } string Hangman::getFormattedAnswer() { return getFormattedAnswe
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;
}
void Hangman::printStatus()
{
cout如果correctAnswer
为空,correctAnswer.begin()
将与correctAnswer.end()
相同,且不可取消引用。如果correctAnswer
为空,correctAnswer.begin()
将与correctAnswer.end()相同
且不可取消引用。我觉得这很好。但是,请记住,任何堆或堆栈损坏都可能导致此错误。您需要获取堆栈跟踪并查看correctAnswer内部,并确保它和相关Hangman实例都是有效对象
还有,我只是有点担心你的函数。它们看起来很奇怪。为什么不用std::for_替换它们呢
Edit@comment:
如果你有C++0x,你可以这样做
std::for_each(correctAnswer.begin(), correctAnswer.end(), [this](const char& ref) {
std::cout << this->displayChar(ref);
});
std::for_each(correctAnswer.begin(),correctAnswer.end(),[this](const char&ref){
std::cout 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);
struct-helper{
刽子手*ptr;
void运算符()(常量字符和引用){
std::cout displayChar(ref);
}
};
帮手;
Helper.ptr=this;
std::for_each(correctAnswer.begin()、correctAnswer.end()、Helper);
我觉得没问题。但是,请记住,任何堆或堆栈损坏都可能导致此错误。您需要获取堆栈跟踪并查看correctAnswer内部,并确保它和相关Hangman实例都是有效对象
还有,我只是有点担心你的函数。它们看起来很奇怪。为什么不用std::for_替换它们呢
Edit@comment:
如果你有C++0x,你可以这样做
std::for_each(correctAnswer.begin(), correctAnswer.end(), [this](const char& ref) {
std::cout << this->displayChar(ref);
});
std::for_each(correctAnswer.begin(),correctAnswer.end(),[this](const char&ref){
std::cout 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);
struct-helper{
刽子手*ptr;
void运算符()(常量字符和引用){
std::cout displayChar(ref);
}
};
帮手;
Helper.ptr=this;
std::for_each(correctAnswer.begin()、correctAnswer.end()、Helper);
问题在于评估:
displayChar(*begin) + getFormattedAnswerFrom(++begin, end)
在执行此语句时,很明显编译器首先递增begin
,返回“next”begin
,作为getFormattedAnswerFrom
的第一个参数,然后取消对begin
参数的引用
当begin
落后于end
时,则begin!=end
因此displayChar(*begin)+getFormattedAnswerFrom(++begin,end)
将运行。您的编译器递增begin
,因此现在begin==end
,并且begin
的取消引用无效
另请参见:问题在于评估:
displayChar(*begin) + getFormattedAnswerFrom(++begin, end)
在执行此语句时,很明显编译器首先递增begin
,返回“next”begin
,作为getFormattedAnswerFrom
的第一个参数,然后取消对begin
参数的引用
当begin
落后于end
时,则begin!=end
因此displayChar(*begin)+getFormattedAnswerFrom(++begin,end)
将运行。您的编译器递增begin
,因此现在begin==end
,并且begin
的取消引用无效
另请参见:您是否可以在调试时尝试获取回溯,以确保您发布的代码会导致这种行为?您使用递归实现是否有特殊原因?迭代实现会更简单。@James是的,您是对的。我以迭代方式实现了它,现在它可以工作了。看起来像是一个由一种类型o导致的错误f issue when begin==end-1您是否可以在调试时尝试获取回溯,以确保您发布的代码会导致这种行为?是否有特定原因导致您使用递归实现?迭代实现会更简单。@James是的,您是对的。我迭代实现了它,现在它可以工作了。看起来像是离线实现当begin==end-1时,有一种类型的问题,但它不应该立即终止递归吗?他对此进行了检查。你是说即使begin==end,displayChar(*begin)+getFormattedAnswerFrom(++begin,end);仍将被计算?@jpalecek:啊,是的,这是真的。但它不应该立即终止递归吗?他对此进行了检查。你是说即使begin==end,displayChar(*begin)+getFormattedAnswerFrom(++begin,end)这是真的。C++规范是否定义了二进制运算符的子表达式求值顺序,或者是通常向右向左,如你的断言?@戴维:它是UB,至少对于原始类型。对于用户类型,它是不被证明的,但是也可能是未定义的(我不知道确切的)。“戴维,我不认为C++标准指定了<代码> *> <代码>还是<代码> ++Stase将首先执行。我不打算断言左表达式的左到右的评价,所以我更新了我的答案。事实上,我曾经在使用英特尔和Visual C++编译器的公司工作过。英特尔编译器倾向于评估左边。右到左,Visual C++编译器倾向于左右对齐。这导致了一些问题,如果用<代码> ICC 编译,有些测试用例会成功,但是如果用< Clult> Cl</代码>编译,失败了。我认为操作的简单顺序是向右的?无论如何,这是为什么要避免++x或x++的另一个例子。作为一个更大的表达式的一部分。C++规范定义二进制操作符的子表达式的顺序吗?或者,通常是向右向左,就像你的断言?@戴维:它是UB,至少是为了