2015-01-12 2 views
3

В настоящее время я ищу способ иметь постоянный указатель на объект внутри списка. По постоянному я имею в виду указатель, который всегда указывает на тот же объект, пока он существует.Получить постоянный указатель на объект в списке

Я не мог найти какой-либо простой способ сделать это, так что у кого-нибудь есть идея? Я уже использую boost, поэтому решение для повышения эффективности также очень приемлемо.

Чтобы пролить свет на то, что мне нужно, вот пример:

std::map<int, std::list<void (*)()> > handlerList; // I store some callback functions like this 

void addHandler(int id, void (*handlerFunc)()) { 
    handlerList[id].push_back(handlerFunc); // 100% intended behavior (I know that the []-operator creates a object if it doesn't exist) 
} 

То, что я хотел бы иметь что-то вроде этого:

some_permanent_pointer_type addHandler(int id, void (*handlerFunc)()) { 
    return handlerList[id].push_back(handlerFunc); 
} 

А потом в какой-то другой точке :

some_permanent_pointer_type handlerPointer; 

handlerPointer = addHandler(123, someFunc); 

// Other point of code 

handlerPointer.delete(); // or 
ListType.delete(handlerPointer); // Or something like this 

У вас есть идеи? Написание собственного класса не было бы такой сделкой. Но я понятия не имею, как это реализовать. Но я предпочел бы что-то уже существующее. Время и прочее.

Примечание: этот код будет работать на Linux-машине.

+0

Вы не можете сделать это, потому что список изменчиво. Если список изменится, местоположение в памяти его объектов может измениться. Вы уже можете найти список обработчиков по id, чтобы вы могли получить его, когда вам это нужно. Всякий раз, когда я вижу такой вопрос, я считаю, что лучше всего сделать шаг назад и спросить, что вы пытаетесь сделать, потому что ответ не идет по этому пути. – mbgda

+0

Вы ищете [делегаты?] (Http://msdn.microsoft.com/en-us/library/hh755798.aspx) –

+0

@FelixCastor - это C++/CX, который отличается от обычного C++. – Borgleader

ответ

2

Вот что-то, что я быстро бросил вместе. В настоящее время звонок destroy() является плохим, но это можно устранить.

#include <map> 
#include <list> 

std::map<int, std::list<void (*)()> > handlerList; 

class HandleHandle { 
    public: 
     HandleHandle(std::list<void (*)()> &list, std::list<void (*)()>::iterator iterator): 
      list_(list), 
      iterator_(iterator) 
     {} 

     void destroy() { 
      list_.erase(iterator_); 
     } 

    private: 
     std::list<void (*)()> & list_; 
     std::list<void (*)()>::iterator iterator_; 
}; 

HandleHandle addHandler(int id, void (*handlerFunc)()) { 
    handlerList[id].push_back(handlerFunc); 
    return HandleHandle(handlerList[id], handlerList[id].rbegin().base()); 
} 

void someFunc() { 
} 

int main() { 
    auto handlerPointer = addHandler(123, someFunc); 
    handlerPointer.destroy(); 
} 
+0

Но если я удалю один объект в середине, все остальные итераторы больше не будут указывать на правильную запись, не так ли? – BrainStone

+2

Из документации для ['std :: list :: erase'] (http://en.cppreference.com/w/cpp/container/list/erase): ссылки и итераторы на стертые элементы недействительны. Другие ссылки и итераторы не затрагиваются. –

+1

Возможно, 'destroy()' должен установить итератор, чтобы указать на 'list_.end() ', а затем это может быть использовано для проверки того, был ли этот« HandleHandle »уже уничтожен. –

0

Из требований вы заявленных, вам ничего не нужно больше, чем

using funclist = std::list<void (*)()>; 
std::map<int, funclist > handlerList; // I store some callback functions like this 

funclist& addHandler(int id, void (*handlerFunc)()) { 
    handlerList[id].push_back(handlerFunc); // Creates list on demand 
    return handlerList[id]; 
} 

auto list5 = addHandler(5, &foo); 
addHandler(5, &bar); 
list5.clear(); // Clears entire handlerList[5], i.e. &foo and &bar. 
+0

Я не хочу очищать весь список. Просто отдельные элементы. – BrainStone

Смежные вопросы