【问题标题】:How to browse a list<Class> In c++如何在 C++ 中浏览列表<Class>
【发布时间】:2022-01-08 12:48:32
【问题描述】:

我在这里遇到了问题,我以为我会在 Internet 上找到一个简单的答案,但已经 1 小时了,我无法解决。看起来很简单,但我找不到方法……

我有 2 节课:

#include <iostream>
#include <list>
using namespace std;

class classB;

class classA{
private :
    string name;
    list<classB*> listClassB;

public:
    void getListClassB() const;
};

class classB{
private:
    string name;
    list<classA*> listClassA;

public:
    void getListClassA() const;
};

我对@9​​87654325@ 方法所做的是:

void classA::getListClassB() const {
    for(list<classB*>::iterator it = listClassB.begin(); it != listClassB.end; it++){
        //Stuff
    }
}

Visual Studio Code 告诉我 listClassB 来自 list&lt;classB*&gt;::iterator it = listClassB.begin() 有一个错误

关于这个的完整错误是:

there is no appropriate user-defined conversion of 
"std::_List_const_iterator<std::_List_val<std::conditional_t<true, std::_List_simple_types<classB *>, std::_List_iter_types<classB *, size_t, ptrdiff_t, classB **, classB *const *, classB *&, classB *const &, std::_List_node<classB *, void *> *>>>>\" in \"std::_List_iterator<std::_List_val<std::conditional_t<true, std::_List_simple_types<classB *>, std::_List_iter_types<classB *, size_t, ptrdiff_t, classB **, classB *const *, classB *&, classB *const &, std::_List_node<classB *, void *> *>>>>"

编辑:

好的,再次感谢您的所有时间,但这个错误让我抓狂。

我完成了一些代码以更明确地说明我的工作。

我没有深入,因为这是法国的大学工作,而且是关于 UML 课程,所以它是与其他课程相关联的课程......

【问题讨论】:

  • 试试(*it)-&gt;str
  • 旁注:lists 的指针并不是那么有用,除非您存储多态对象。 list 非常宽容 iterator invalidation rules 所以你不必担心插入和删除会搞砸事情,所以如果你动态分配Whatevers.
  • iterator it = myList.begin() 是正确的,错误在于您取消引用的方式。试图改变初始化迭代器的方式只会让事情变得更糟。
  • 如果您仍然遇到问题,您应该创建一个实际的minimal reproducible example。在您的示例中,类定义的末尾没有;,也没有使Whatever wtvr("hey"); 工作的构造函数。如果我纠正这两个问题 正确取消引用迭代器,它对我来说很好。 ideone.com/FelLN9
  • 您的函数标记为const,因此您必须使用const_iterator,而不是iterator。否则你就违反了语言规则。您在循环中调用 end() 时也缺少括号。

标签: c++ list loops class iterator


【解决方案1】:

首先,迭代器是一个指针语义对象,因此您必须取消引用它才能访问实际对象。 it.str 没有意义,因为 std::list&lt;&gt;::iterator 没有 str 成员(即使有,也与 str 类的 Whatever 成员无关。

其次,您的列表元素本身就是指针,因此这意味着您需要第二次间接访问str 成员:

std::cout << (*(*it)).str;

更吸引人的语法是:

std::cout << (*it)->str;

【讨论】:

  • 感谢您的编辑。在您声称-&gt; 会神奇地遵循一系列指针之后,我做了双重考虑。那对我来说是个新闻! ;)
  • 不一样。我的错误是没有注意到列表正在存储指针,因为问题的标题是关于list&lt;Class&gt;。我想其他 3 个人也落入了同一个陷阱! :)
  • 是的。 差点把这个问题作为一个错字结束,直到我发现了那个小并发症。
  • 等等,为什么单个-&gt; 工作?我认为这就是-&gt; 规则的意义所在,它允许您执行std::unique_ptr&lt;Foo&gt; pFoo; pFoo-&gt;fooMember;
  • @NathanPierson 为了让-&gt; 继续取消引用,它应该返回类似指针的对象,而不是实际的指针 - 它在实际找到指针时停止链,并且迭代器的 operator-&gt; 返回一个指针.
【解决方案2】:

包含所有模板内容的错误消息很难阅读,但基本上可以归结为:

there is no appropriate user-defined conversion of 
"std::_List_const_iterator<>" in "std::_List_iterator<>"

getListClassB() 被标记为const,因此它的this 指针类型为const classA *,因此listClassB 成员在通过this 访问时隐式为const

当在const list 对象上调用list::begin() 时,它会返回一个list::const_iterator,您的循环试图将其分配给list::iterator,这是不允许的,因此会出现错误。 list::iterator 允许修改 list 数据,而 list::const_iterator 不允许。这就是为什么不能将 const_iterator 分配给 iterator 的原因。

话虽如此,您的for 循环中有另一个错字。您需要将listClassB.end 改为listClassB.end()(注意额外的括号),即您需要调用 end() 并将其返回值it 进行比较,而不是将 end 本身it 进行比较。

试试这个:

void classA::getListClassB() const {
    for(list<classB*>::const_iterator it = listClassB.begin(); it != listClassB.end(); ++it){
        //Stuff
    }
}

但是请注意,如果您使用auto 来让编译器推断it 提供适当的类型,则可以避免const_iterator/iterator 不匹配,例如:

void classA::getListClassB() const {
    for(auto it = listClassB.begin(); it != listClassB.end(); ++it){
        //Stuff
    }
}

但是,避免这两个错误的更安全方法是使用range-for 循环,例如:

void classA::getListClassB() const {
    for(classB *ptr : listClassB){
        //Stuff
    }
}

【讨论】:

    猜你喜欢
    • 2017-11-12
    • 2017-08-19
    • 2019-02-19
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    相关资源
    最近更新 更多