2015-02-23 3 views
0

По этой теме Returning a pointer to a vector element, рекомендуется использовать следующий код при вставке объекта в вектор и возвращающегося его указатель:Удаление элемента из станд :: список станд :: unique_pointer

// in your class 
std::vector<std::unique_ptr<SceneGraphNode>> m_children; 

SceneGraphNode* addChild(std::string name) 
{ 
    std::unique_ptr<SceneGraphNode> child(new SceneGraphNode(this,name)); 
    myList.push_back(std::move(child)); 
    return myList.back().get(); 
} 

I планируете использовать тот же код, но с std::list. У меня теперь нет проблемы с перераспределением, но std::unique_ptr все еще помогает при уничтожении вектора - вместо простого delete.

Вопрос: Как использовать список remove с этой настройкой? С помощью простых указателей я мог бы просто написать myList.remove(myPtr), где myPtr - простой указатель на объект для удаления.

+1

Обратите внимание, что даже при использовании объекта «std :: vector» все значение перераспределения на размер изменяется часто быстрее, чем 'std :: list' (хотя на самом деле вы не располагаете данными с помощью' станд :: unique_ptr's). – rubenvb

+0

@rubenvb вы по-прежнему получаете дополнительную локальность данных, не требуя двух разметки указателя для доступа к элементу. Сокращение вдвое числа различий может оказать существенное влияние в зависимости от приложения. – sjdowling

ответ

2

Вы все еще можете сделать myList.remove(myPtr), если myPtr является unique_ptr. Это происходит потому, что operator== перегружен для таких умных указателей: http://en.cppreference.com/w/cpp/memory/unique_ptr/operator_cmp

+0

Но для этого потребуется создать второй 'unique_ptr' для' myPtr' перед вызовом метода remove: 'myList.remove (unique_ptr (myPtr))'. Разве это не проблема? – Michael

+0

@Michael Вам просто нужна ссылка на 'unique_ptr', которую вы пытаетесь удалить из списка. Тогда 'operator ==' возвращает true, когда 'unique_ptr' сравнивается с самим собой. – sjdowling

0

Может быть что-то вроде это будет полезно:

it = find(myList.begin(), myList.end(), name); 
if (it != myList.end()) 
{ 
    mylist.erase(it); 
} 
1

Если вы действительно хотите использовать простой указатель как myPtr вы можете использовать

myList.remove_if([myPtr](const std::unique_ptr<SceneGraphNode>& ptr){return ptr.get() == myPtr}); 
Смежные вопросы