I'm having a problem here and I thought I would find an easy answer on the Internet, but it's been 1 hour and I can't solve it. Seems so simple, but I can't find a way...
I've got 2 classes:
#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;
};
What I do on the getListClassB()
method is:
void classA::getListClassB() const {
for(list<classB*>::iterator it = listClassB.begin(); it != listClassB.end; it ){
//Stuff
}
}
Visual Studio Code tells me that there is an error is on listClassB
from list<classB*>::iterator it = listClassB.begin()
The complete error about that is:
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 *> *>>>>"
EDIT:
Ok, so thanks again for all your time, but this error makes me crazy.
I completed a bit the code to be more explicit about my work.
I don't go deeper because it's college work in France, and it's about UML classes, so it's class linked with others classes...
CodePudding user response:
First, iterator is a pointer semantic object, so you have to dereference it to access the actual object. it.str
makes no sense, since std::list<>::iterator
has no str
member (and even if it did, that would have nothing to do with str
member of Whatever
class.
Second, your list elements are pointers themselves, so this means you need a second indirection in order to access the str
member:
std::cout << (*(*it)).str;
More appealing syntax would be:
std::cout << (*it)->str;
CodePudding user response:
The error message is difficult to read with all the template stuff in it, but it basically boils down to this:
there is no appropriate user-defined conversion of
"std::_List_const_iterator<>" in "std::_List_iterator<>"
getListClassB()
is marked as const
, so its this
pointer is typed as const classA *
, thus the listClassB
member is implicitly const
when accessed via this
.
When list::begin()
is called on a const list
object, it returns a list::const_iterator
, which your loop is trying to assign to a list::iterator
, which is not allowed, hence the error. list::iterator
allows the list
data to be modified, whereas list::const_iterator
does not. Which is why a const_iterator
cannot be assigned to an iterator
.
That being said, your for
loop has another typo in it. You need to change listClassB.end
to listClassB.end()
instead (notice the extra parenthesis), ie you need to call end()
and compare its return value to it
, not compare end
itself to it
.
Try this instead:
void classA::getListClassB() const {
for(list<classB*>::const_iterator it = listClassB.begin(); it != listClassB.end(); it){
//Stuff
}
}
Note, however, that the const_iterator
/iterator
mismatch could have been avoided if you had used auto
instead to let the compiler deduce the appropriate type for it
, eg:
void classA::getListClassB() const {
for(auto it = listClassB.begin(); it != listClassB.end(); it){
//Stuff
}
}
But, a safer way to avoid both mistakes would be to use a range-for
loop instead, eg:
void classA::getListClassB() const {
for(classB *ptr : listClassB){
//Stuff
}
}