【问题标题】:STL list<mystruct> return problemSTL list<mystruct> 返回问题
【发布时间】:2011-08-02 03:07:06
【问题描述】:

我正在尝试在项目中使用 STL 列表,但我遇到了以下问题。

我希望我的列表存储一个结构。比如这个

struct mystruct
{
    int x;
    int y;
};

然后我使用迭代器像这样访问列表中的每个结构。

list<mystruct> L;
list<mystruct>::iterator lit;
for(lit=L.begin();lit!=L.end();lit++) 
    {
        if(lit->x==1) cout << "<NUM," << lit->x << "> ";
        if(lit->y==2) cout << "<ID," << lit->y << "> ";
    }

这可行,但我想一次得到一个结构,所以我做了这个函数

mystruct Myclass::next(void)
{
    if(lit!=L.end()) 
    {
        lit++;
    }
    return *lit;
}

但我在运行它后出现错误,我无法理解为什么会发生这种情况。

有什么想法吗?

【问题讨论】:

  • 什么是错误,Myclass的接口是什么? (以成员为例)
  • 只是一个建议,当使用迭代器时(像你一样,在 for 循环等中)使用前缀增量(++lit 而不是 lit++),它更有效。
  • 错误是“列表迭代器不可递增”。

标签: c++ list stl iterator next


【解决方案1】:
mystruct Myclass::next(void)
{
    if(lit!=L.end()) 
    {
        lit++;
    }
    return *lit;
}

除非您已经在末尾,否则您会递增,但每次都会取消引用,无论您是否位于末尾。为了帮助解决这个问题,请考虑返回一个指针,如果您在最后,则返回一个 0 指针。

mystruct* Myclass::next(void)
{
    if(lit!=L.end() && ++lit != L.end()) 
    {
        // dereference to get the struct, and then return the address of the struct
        return &*lit;
    }
    return 0;
    // or nullptr in C++0x
}

然后在您使用Myclass::next 的代码中再次检查0(或nullptr)。

【讨论】:

  • -1。错误的解决方案。如果在if 块内,如果lit++ 使lit 到达终点怎么办?未定义的行为。你需要检查之后 lit++.
  • @Nawaz:哦,我的错。那是我想得有点快,更正了。感谢您指出这一点。
【解决方案2】:

如果您正在编写返回对象(而不是指针)的 next(),那么我认为您还需要编写 has_next() 函数,您应该调用该函数来检查列表中是否有项目,之前打电话给next()。像这样的:

bool has_next()
{
   list<mystruct>::iterator temp = lit;
   return ++temp != L.end();
}

mystruct Myclass::next(void)
{
    if( !has_next()) 
    {
         throw "end of the list is reached";
    }
    ++lit;
    return *lit;
}

//usage
while(myClassInstance.has_next())
{
      mystruct s = myClassInstance.next();
      //work with s
}

或者,如果您决定从 next() 返回指向 mystruct 的指针,则不需要 has_next()。你可以这样写:

mystruct *  Myclass::next(void)
{
    ++lit;
    if( lit == L.end() ) 
         return NULL;
    return &(*lit);
}

【讨论】:

  • 有一个问题,++lit 是否仍会评估为 L.end(),如果它是之前的结尾?
  • @Xeo:不。那将是未定义的行为。但我认为调用者有责任确保它不会在返回NULL 后调用next(),就像当it 到达end() 时你不会调用++it
  • @Nawaz "列表迭代器不可递增"
  • @fokpop:如果您不发布所有相关代码以及编译器打印的“确切”错误,则无法为您提供帮助。
【解决方案3】:

问题就在这里:

mystruct Myclass::next(void)
{
    if(lit!=L.end()) 
    {
        lit++;
    }
    return *lit;
}

首先如何定义lit?
其次,如果 lit 等于 L.end() 你应该返回一些默认值,而不是取消引用它,因为如果你这样做,你会导致一个未定义的行为。如果运气好,你的程序会崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2020-02-25
    • 1970-01-01
    • 2015-06-05
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多