Могу ли я получить указатель на текущее значение итератора - PullRequest
6 голосов
/ 23 декабря 2011

В моем классе у меня есть два частных участника:

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

Когда происходит событие, я бы хотел пройтись по списку и запустить какой-то тест, который даст только true для одного из элементов в списке. Я хотел бы сохранить указатель на этот элемент для использования в другом месте.

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

В другом месте В другом методе

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

Однако это не работает, потому что i не указатель, а итератор, даже если вы можете рассматривать его как указатель на MyObject.

Можно ли извлечь указатель, который итератор хранит внутри для использования в другом месте?

Я неправильно думаю об этом?

Как правильно выполнить то, что я пытаюсь сделать?

Ответы [ 2 ]

14 голосов
/ 23 декабря 2011

Можно ли извлечь указатель, который итератор хранит внутри для использования в другом месте?

Конечно, просто разыменовываем итератор с помощью *, а затем получаем указатель на объект через &:

selectedObj = &*i;

Кстати, вы не забыли инициализировать selectedObj с NULL перед циклом?

6 голосов
/ 23 декабря 2011

Можно ли извлечь указатель, который итератор хранит внутри для использования в другом месте?

Да. Как сказал @FredOverflow, сделайте следующее:

selectedObj = &*i;

Тем не менее, если вы можете использовать функции C ++ 11, то вы можете получить удовольствие от написания лучшего синтаксиса, используя цикл for на основе диапазона, например:

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

выглядит лучше? Нет необходимости в итераторе и написании синтаксиса типа &*i. Следует также отметить, что если класс MyObject перегружен operator &, то &*i не будет работать, так как вызовет функцию operator& вместо того, чтобы получить адрес объекта! Если это так, то вы пишете (MyObject*)&(char&)*i, чтобы получить адрес *i, или в C ++ 11 вы можете использовать std::addressof(*i), который вы можете определить сами, если не можете использовать C ++ 11:

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

Код взят здесь: std :: addressof

...