2011-12-23 7 views
5

W mojej klasie mam dwie prywatne członków:mogę uzyskać wskaźnik do aktualnej wartości iteratora

std::list<MyObject> objects; 
MyObject *selecteObj; 

Gdy wystąpi zdarzenie Chciałbym iterację listy i uruchomić jakiś rodzaj testu, który będzie ustępuje tylko na jednej z pozycji na liście. Chciałbym zapisać wskaźnik do tego elementu do użycia w innym miejscu.

std::list<MyObject>::iterator i; 
for (i = objects.begin(); i!=objects.end(); ++i){ 
    if (i->test()) 
     selectedObj = i; 
} 

gdzie indziej w innym sposobie

if (selectedObj !=null) 
    tmpObj->doSomething(); 

Jednak to nie działa, ponieważ i nie jest wskaźnikiem jego iterator chociaż można traktować jak wskaźnik do MyObject.

Czy można pobrać wskaźnik, który iterator przechowuje wewnętrznie, aby móc go użyć gdzie indziej?

Czy źle o tym myślę?

Jaki jest właściwy sposób realizacji tego, co próbuję zrobić?

Odpowiedz

12

Czy możliwe jest pobranie wskaźnika, który iterator przechowuje wewnętrznie do użycia w innym miejscu?

Jasne, tylko dereference iteracyjnej z * a następnie uzyskać wskaźnik do obiektu poprzez &:

selectedObj = &*i; 

Na marginesie, nie pamiętać, aby zainicjować selectedObj z NULL przed pętli?

+1

Z pewnością masz na myśli 'std :: addressof (* i)', nie? OP nie pytał, jak wywołać obiekt '&' -operator ... –

+0

@KerrekSB: Myślę, że chodziło o 'std :: addressof' (zamiast' std :: address_of'), nieprawdaż? : P – Nawaz

+0

@Nawaz: oh, co powiedziałem * ja *? ;-) –

6

Czy możliwe jest pobranie wskaźnika, który iterator przechowuje wewnętrznie do użycia w innym miejscu?

Tak. Jak powiedział @FredOverflow, to zrobić:

selectedObj = &*i; 

Jednakże, jeśli można użyć funkcji C++ 11, a następnie można cieszyć się pisać lepsze składni przy użyciu zakres opartefor pętlę jako:

MyObject *selectedObj = NULL; 
for (MyObject & obj : objects) 
{ 
    if (obj.test()) 
     selectedObj = &obj; //store the address 
} 

Wygląda lepiej? Nie potrzeba iteratora i pisania składni, jak &*i. Należy również zauważyć, że jeśli klasa MyObject przeładowała operator &, wówczas &*i nie zadziała, ponieważ wywoła funkcję operator&, zamiast otrzymywać adres obiektu! Jeśli tak, to masz napisać (MyObject*)&(char&)*i aby uzyskać adres *i, czy w C++ 11 można użyć std::addressof(*i) który można określić samodzielnie, jeśli nie można używać C++ 11:

template< class T > 
T* addressof(T& arg) { 
    return (T*)&(char&)arg; 
} 

Kod pochodzi z tutaj: std::addressof