C++ 奇怪的迭代器行为 #包括“stdafx.h” int _tmain(int argc,_TCHAR*argv[] { string s=“不知道为什么。”; 自动beg=s.begin(); 自动结束=s.结束(); while(beg
存储在C++ 奇怪的迭代器行为 #包括“stdafx.h” int _tmain(int argc,_TCHAR*argv[] { string s=“不知道为什么。”; 自动beg=s.begin(); 自动结束=s.结束(); while(beg,c++,iterator,C++,Iterator,存储在end中的上一个s.end()值在s.erase()之后无效。因此,不要使用它。此代码有几个问题 不要缓存s.end()的值;它会随着删除元素而更改 不要使用beg
end
中的上一个s.end()值在s.erase()之后无效。因此,不要使用它。此代码有几个问题
s.end()
的值;它会随着删除元素而更改beg
。惯用的方法是编写beg!=end
。如果试图迭代过去的end
,结果是未定义的,并且字符串库的调试版本可能会故意使进程崩溃,因此使用是没有意义的。请注意基本字符串及其迭代器的语义
来自www.ski.com/tech/stl
注意到,根据C++标准,Basic字符串具有非常不寻常的迭代器失效语义。迭代器可能被交换、保留、插入和擦除(以及等效于插入和/或擦除的函数,如清除、调整大小、追加和替换)无效。。此外,对任何非常量成员函数的第一次调用,包括begin()或运算符[]的非常量版本,可能会使迭代器无效。(这些迭代器无效规则的目的是让实现者在实现技术上有更大的自由度。)
如果
int _tmain(int argc, _TCHAR* argv[])
{
string s = "Haven't got an idea why.";
for (auto beg = s.begin(); beg != s.end();)
{
cout << *beg << '\n';
if (*beg == 'a')
{//whithout if construct it works perfectly
beg = s.erase(beg);
}
else
{
++beg;
}
}
}
返回一个迭代器,该迭代器等效于end()从向量或字符串中逐个删除元素具有二次复杂度。有更好的线性复杂度解决方案:
beg = s.erase(beg);
#包括
#包括
int main()
{
std::string s=“我不知道为什么。”;
s、 擦除(std::remove(s.begin()、s.end()、'a')、s.end());
std::cout在调用擦除操作时,存储的结束迭代器指针无效。因此,在while循环条件中使用s.end()函数您必须从.end()-1迭代到.begin()。同时,使用==和!=以外的比较运算符是不安全的
这是我的密码:
#include <string>
#include <algorithm>
int main()
{
std::string s = "Haven't got an idea why.";
s.erase(std::remove(s.begin(), s.end(), 'a'), s.end());
std::cout << s << std::endl;
}
vector myVector(my,my+myCount);
//对顶部相关数据计数进行排序和迭代
排序(myVector.begin(),myVector.end());
我能肯定你是对的,但这没有多大意义,是吗?为什么结尾迭代器会无效?@A-ha:它是根据定义无效的。标准是这么说的。@A-ha标准说了什么(正如马塞洛正确指出的)有很好的理由这样做。迭代器正在查看字符串的结束位置,而您删除了其中的一个字符。逻辑上,它以前的值不再有效。如果要检查新的结束,必须再次询问容器(s.end()),不使用以前缓存的值。从end()
到begin()
擦除字符可能更容易,因为begin()
在擦除字符时不会更改。“不要缓存s.end()的值;它会随着删除元素而更改。”我的auto
主要问题之一。请查看auto end=s.end()
并告诉我,这不会误导语言新手![一般性评论;不是特别指本OP]@托马拉克:我同意,auto
这个不自明的意思是不幸的,但你是说选择使用auto
是不正确的吗?@Tomalak:我刚刚意识到我的问题模棱两可,我不确定你回答的是哪种解释。所以,说清楚点,我不是说,“我使用auto
是不是不正确?”我的意思是,“你认为语言设计者在选择auto
进行类型推断时选择得不好吗?”很抱歉给你带来了困惑。@Marcel:Aha。现在的答案是“是的,可能吧。”"@ Tomalak:我同意选择并不理想。但是当向一个语言添加关键字时,总是有一个折衷:你将打破多少现有程序?随着大量现存的C++代码,一个几乎没有人会使用的变量/函数/类/等名称的单个新关键字可能会破坏数万个程序。他真正的选择是在一个更容易混淆的语法技巧,还是选择一个现有的关键字。我的感觉是,对于新用户来说,一个小小的暂时性混淆可以被避免一个新关键字所抵消。
#include <string>
#include <algorithm>
int main()
{
std::string s = "Haven't got an idea why.";
s.erase(std::remove(s.begin(), s.end(), 'a'), s.end());
std::cout << s << std::endl;
}
vector<long long> myVector (my, my+myCount);
//sort and iterate through top correlation data counts
sort (myVector.begin(), myVector.end());
cout << endl;
int TopCorrelationDataCount = 0;
bool myVectorIterator_lastItem = false;
vector<long long>::iterator myVectorIterator=myVector.end()-1;
while (true) {
long long storedData = *myVectorIterator;
cout << TopCorrelationDataCount << " " << storedData << endl;
//prepare for next item
TopCorrelationDataCount++;
//if (TopCorrelationDataCount >= this->TopCorrelationDataSize) break;
if (myVectorIterator_lastItem) break;
myVectorIterator--;
if (myVectorIterator==myVector.begin())
{
myVectorIterator_lastItem = true;
}
}