Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 奇怪的迭代器行为 #包括“stdafx.h” int _tmain(int argc,_TCHAR*argv[] { string s=“不知道为什么。”; 自动beg=s.begin(); 自动结束=s.结束(); while(beg_C++_Iterator - Fatal编程技术网

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;
            }
        }