Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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++ 自定义迭代器未取消引用问题_C++_List_Vector_Iterator - Fatal编程技术网

C++ 自定义迭代器未取消引用问题

C++ 自定义迭代器未取消引用问题,c++,list,vector,iterator,C++,List,Vector,Iterator,下面是实现std::list迭代器的第一次尝试: 文件.h 预期产出: aaaaaaaaaa 我得到的不是上述预期输出: 调试断言失败表达式:列表迭代器不可取消引用 为什么我会有这种行为?如何纠正 注意:经过简短的研究,我发现这种行为最常见的原因是试图取消引用end迭代器,但我在代码中找不到这种表达式。您正在取消引用Document::end中的end迭代器*text.end。最容易解决的问题是在Document::begin中使用list::back和list::front 当您修复了这个问题

下面是实现std::list迭代器的第一次尝试:

文件.h

预期产出:

aaaaaaaaaa

我得到的不是上述预期输出:

调试断言失败表达式:列表迭代器不可取消引用

为什么我会有这种行为?如何纠正


注意:经过简短的研究,我发现这种行为最常见的原因是试图取消引用end迭代器,但我在代码中找不到这种表达式。

您正在取消引用Document::end中的end迭代器*text.end。最容易解决的问题是在Document::begin中使用list::back和list::front

当您修复了这个问题后,您会发现Text_iterator::operator++也会取消对end迭代器的引用,因为您没有针对适当的end检查ln@Jonathan Potter的评论是对的,您需要将text.end传递给两个text_迭代器

变化:

class Text_iterator
{
    // Declarations elided
private:
    std::list<Line>::iterator ln;
    std::list<Line>::iterator ln_end;
    Line::iterator pos;        
}

Text_iterator::Text_iterator(std::list<Line>::iterator l, std::list<Line>::iterator l_end, Line::iterator p)
    : ln(l), ln_end(l_end), pos(p) { }

Text_iterator::Text_iterator(const Text_iterator& src)
    : ln(src.ln), ln_end(src.ln_end), pos(src.pos) { }

Text_iterator& Text_iterator::operator++ ()
{
    ++pos;
    if (pos == ln->end())        
    {
        ++ln;
        if(ln != ln_end)
        {
            pos = ln->begin();
        }
    }
    return *this;
}

void Text_iterator::swap(Text_iterator& src)
{
    std::swap(src.ln, ln);
    std::swap(src.ln_end, ln_end);
    std::swap(src.pos, pos);
}

Document::iterator Document::begin()
{ 
    return iterator(text.begin(), text.end(), text.front().begin());
}

Document::iterator Document::end()
{ 
    return iterator(text.end(), text.end(), text.back().end());
}

当最终增量出现时,pos将指向最后一行的结束迭代器,ln将指向文本的结束迭代器,这就是我们在Document::end中传递给文本迭代器构造函数的内容。我们不需要比较或公开文本迭代器::ln_end来保留合理的语义。

迭代器需要存储每个容器的末尾和开头。
#include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <algorithm>
#include "Document.h"

int main()
{
    Document text;
    text.print();
}
class Text_iterator
{
    // Declarations elided
private:
    std::list<Line>::iterator ln;
    std::list<Line>::iterator ln_end;
    Line::iterator pos;        
}

Text_iterator::Text_iterator(std::list<Line>::iterator l, std::list<Line>::iterator l_end, Line::iterator p)
    : ln(l), ln_end(l_end), pos(p) { }

Text_iterator::Text_iterator(const Text_iterator& src)
    : ln(src.ln), ln_end(src.ln_end), pos(src.pos) { }

Text_iterator& Text_iterator::operator++ ()
{
    ++pos;
    if (pos == ln->end())        
    {
        ++ln;
        if(ln != ln_end)
        {
            pos = ln->begin();
        }
    }
    return *this;
}

void Text_iterator::swap(Text_iterator& src)
{
    std::swap(src.ln, ln);
    std::swap(src.ln_end, ln_end);
    std::swap(src.pos, pos);
}

Document::iterator Document::begin()
{ 
    return iterator(text.begin(), text.end(), text.front().begin());
}

Document::iterator Document::end()
{ 
    return iterator(text.end(), text.end(), text.back().end());
}