Doubt with lists

1

I have a question about why this error occurs in the code described below:

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



class List {
    list<int> m_list;
    list<int>::iterator it;
public:
    void loadList();
    void Element(list<int> l);
    int Element2(list<int> l, list<int>::iterator it);
};

void List::loadList() {
    m_list.push_back(3);
    m_list.push_back(4);
    m_list.push_back(5);
    m_list.push_back(7);
    m_list.push_back(9);
    Element(m_list);
}



void List::Element(list<int> l) {
    it = l.begin();
    int higher = Element2(l, it);
}
int List::Element2(list<int> l, list<int>::iterator it) {
    int higher = *(l.begin());
    if (l.begin() == it) { //Excepción no controlada en 0x0F4AE906.Se pasó un parámetro no válido
                            //a una función que produce un error irrecuperable si se especifican
                        //parámetros no válidos.
        cout << "hi";
    }
    return higher;
}


int main() {
    List l;
    l.loadList();
    system("pause");
    return 0;
}

I do not understand what that exception is. Does anyone know?

Do not listen to what the program really does, it's just a "representation" of the code to show the error.

    
asked by Chariot 22.11.2018 в 01:07
source

1 answer

4

The program has one drawback: you are creating copies of the lists

void List::Element(list<int> l) { // l es una copia de la lista original
    it = l.begin();
    int higher = Element2(l, it);
}

int List::Element2(list<int> l, list<int>::iterator it) { // l es una copia de la 'l'  de Element()
    int higher = *(l.begin());
    if (l.begin() == it) { //Excepción no controlada en 0x0F4AE906.Se pasó un parámetro no válido
                            //a una función que produce un error irrecuperable si se especifican
                        //parámetros no válidos.
        cout << "hi";
    }
    return higher;
}

And why is this a problem? Basically because the C ++ standard says so. So the C ++ 0x draft says the following:

  

§ 24.2.1

     

An iterator j is called reachable from an iterator if and only if there is a finite sequence of applications of the expression ++ i that makes i == j. If j is reachable from i, they refer to elements of the same sequence.

     

§ 24.2.5

     

The domain of == for forward iterators is that of iterators over the same underlying sequence.

Summing up and in Spanish:

  • The first point says that two iterators belong to the same sequence if there is a sequence of increments that allows reaching from one iterator to the other.

  • The second point says that the comparison of iterators is safe only if they both belong to the same sequence.

That is, two iterators of two different lists should not be compared to each other because they belong to different sequences.

The standard does not specify that the comparison should not be made, it only specifies what the scope of the comparison operator is. This means that using the operator outside of this scope can work as expected ... or not.

The solution? Use references This way you will not create copies of the lists and the iterators will belong to the same sequence

void List::Element(list<int> & l) {
//                           ~ Referencia

int List::Element2(list<int> & l, list<int>::iterator it) {
//                           ~ Referencia

Now, if the list is not going to change, it would be advisable that the reference be constant:

void List::Element(list<int> const& l) {
//                           ~~~~~~ Referencia constante

int List::Element2(list<int> const& l, list<int>::iterator it) {
//                           ~~~~~~ Referencia constante
    
answered by 22.11.2018 / 12:21
source