5

Ten kod jest uproszczonym testem dla czegoś, co próbuję zrobić naprawdę gdzie indziej. Mam funkcję, która pobiera argument "ref-to-ptr" i modyfikuje go, aby zwrócić wskaźnik z listy wskaźników.Czy przypisanie z dereferencji const_iterator może spowodować niezdefiniowane zachowanie?

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

typedef int* intp; 
typedef std::list<intp> intplist; 
intplist myList; 

void func(intp &arg) // (1) 
{ 
    intplist::const_iterator it = myList.begin(); 
    std::advance(it, 2); 
    arg = *it; 
} 

int main() 
{ 
    myList.push_back(new int(1)); 
    myList.push_back(new int(2)); 
    myList.push_back(new int(3)); 

    int* ip = NULL; // (2) 
    func(ip); 
    if (ip) cout << "ip = " << *ip << endl; 
    else cout << "ip is null!" << endl; 

    for (intplist::const_iterator it = myList.begin(); it != myList.end(); ++it) 
     delete *it; 
    return 0; 
} 

To działa i drukuje ip = 3 zgodnie z oczekiwaniami, tylko obawiam się, że może to być przyczyną niezdefiniowanej zachowanie lub w inny sposób doprowadzić do kłopotów, dlatego jestem stripping dala constness z iteracyjnej przypisując wynikiem To dereferencing do argument. Próbowałem dodać const w (1) i (2), ale nie zbudowałem.

Czy mam prawo się martwić? Jeśli tak, dlaczego nie otrzymuję ostrzeżenia z g ++ (4.9.2)?

+1

"Próbowałem dodać const w (1) i (2), ale nie zbudowałem.": Czy ty też dodać 'const' do' intp' typedef? – Petr

+0

Nie ... Traktowałem typedef jako głupie makro zastępujące ciągi i właśnie umieściłem const w deklaracji 'func': void func (const intp & arg)'. Wasz sposób, buduje i działa, ale nie rozumiem, na czym polega różnica. – neuviemeporte

+0

'intp' jest wskaźnikiem. "const intp" jest stałym wskaźnikiem, nie mówi nic o stałej wartości, na którą wskazuje. Kiedy mówisz 'typedef const int * intp', mówisz, że wskaże on całkowitą liczbę całkowitą. – Petr

Odpowiedz

5

Kod jest całkowicie w porządku. Nie pozbędziesz się żadnej stałej (nie ma sposobu, aby to zrobić pośrednio w C++). *it daje const intp &. Jesteś kopiowanie wskaźnik, o którym mowa w tym odwołanie do arg. Kopiowanie z czegoś nie pozbawia konsternacji. Przypisanie do arg przypisuje się w twoim przypadku do ip, nie wiąże się ono z niczego bezpośrednio z obiektem intp wewnątrz kontenera.

+0

Jeśli czytam to poprawnie, oznacza to, że '* it' jest" odniesieniem do wskaźnika do const int ". Jak to możliwe, że mogę przypisać to do 'val', które jest" odniesieniem do wskaźnika do int "(nie const)? – neuviemeporte

+0

OK, myślę, że teraz rozumiem - jest to "const reference to pointer-to-int", prawda? Wskaźnik nigdy nie był stały. – neuviemeporte

+0

@neuviemeporte Tak, it'a "odniesienie do a (stała (wskaźnik do int))". Nawiasy używane w znaczeniu matematycznym. – Angew

2

const_iterator oznacza po prostu, że nie można przypisać do tego iteratora i/lub można wywoływać tylko funkcje const na obiekcie, który wskazuje. Nie ma problemu z kopiowaniem value - w tym przypadku wskaźnika. Nie przechowujesz stałych wskaźników, gdybyś był, to musiałbyś przypisać do wskaźnika const