Search code examples
c++vectorstliteratorconstants

No viable conversion from '__wrap_iter<std::__1::vector<MenuItem *>::const_pointer>' to '__wrap_iter<std::__1::vector<MenuItem>::pointer>'


I am working on a file that I have to iterate through the object's vector but for some reason I am getting this error:

No viable conversion from '__wrap_iter<std::__1::vector<MenuItem *>::const_pointer>' to '__wrap_iter<std::__1::vector<MenuItem>::pointer>'

this is the line which causes the error:

for (vector<MenuItem>::iterator p = m->menuItems()->begin() ; p != m->menuItems()->end(); p++) {

the class function which I am trying to iterate through:

 virtual const vector<MenuItem*>* menuItems() const = 0;

** the virtual function at the derived classes are:

virtual const vector<MenuItem*>* menuItems() const { return nullptr; }

virtual const vector<MenuItem*>* menuItems() const { return &m_menuItems; }

Edit:

After finding what I wanted to find with the iterator, I want to recall this function (recursive call) with the newfound item. however, when I am trying to do so, I am not matching the function call. the function call is :

 void listAll(const MenuItem* m)

the way I

for (vector<MenuItem*>::const_iterator p = m->menuItems()->begin() ; p != m->menuItems()->end(); p++) {
    cout << (*p)->name();
    if ((*p)->menuItems() == nullptr) {
        cout << endl;
    }
    if ((*p)->menuItems() != nullptr) {
        cout << endl;
        vector<MenuItem*>::const_iterator k = (*p)->menuItems()->begin();
        MenuItem* mPtr = *k;
        listAll(mPtr);

Solution

  • There are two problems here. First, a function with the signature

    const vector<MenuItem*>* menuItems() const;
    

    (virtual or not) returns a pointer to a const-qualified instance of a vector. The begin() and end() member functions of const-qualfied vectors return const_iterators, not iterators. As it makes sense that you can't convert a const_iterator into an iterator, this is an issue.

    Second, you are missing an asterisk in the type of the iterator. So the correct type specifier should be

    vector<MenuItem*>::const_iterator p = m->menuItems()->begin(); ...
    //             ^   ^^^^^^
    

    Using auto type deduction for iterator types is a common pattern, so you could also do

    for (auto p = m->menuItems()->begin() ; p != m->menuItems()->end(); p++)
        { /* ... */ }