Удалить из std :: set <shared_ptr <T>> с помощью T * - PullRequest
4 голосов
/ 28 марта 2010

У меня есть набор общих указателей:

std::set<boost::shared_ptr<T>> set;

И указатель:

T* p;

Я бы хотел эффективно удалить элемент set, равный p, но я не могу сделать это ни с одним из членов набора, или с любым из стандартных алгоритмов, поскольку T* - это совершенно другой тип, чем boost::shared_ptr<T>.

Вот несколько подходов, о которых я могу подумать:

  • каким-то образом создаёт новый shared_ptr из указателя, который не станет владельцем указанной памяти (идеальное решение, но я не вижу, как это сделать)
  • упаковка / повторная реализация shared_ptr, чтобы я мог сделать выше
  • просто делаю собственный бинарный поиск по набору

Ответы [ 3 ]

9 голосов
/ 28 марта 2010

Создайте shared_ptr<T> из T с null_deleter (см. boost ::: shared_ptr FAQ ).

struct null_deleter {
    void operator()(void const *) const { }
};

size_t remove_ptr_from_set(std::set<boost::shared_ptr<T>> &set, X* x)
{
    shared_ptr<X> px(x, null_deleter());
    return set.erase(px);
}

Таким образом, типы совместимы, и вам не нужно беспокоиться о временном удалении shared_ptr любого объекта.

Или, как говорится в одном из комментариев, если вы можете изменить T для наследования от enable_shared_from_this , вы можете получить правильный общий ptr из вашего объекта.

1 голос
/ 28 марта 2010

Вы можете использовать boost::ptr_set, если хотите, чтобы набор владел объектами, или boost::reference_wrapper, если вы просто хотите, чтобы набор сохранял ссылки на них. Если вы используете shared_ptr в одном месте своего кода, вам придется использовать его везде, или вы рискуете ужасными сбоями (висячие указатели, уже удаленные объекты и т. Д.). Исключением является weak_ptr, указатель, который указывает на объект, находящийся у shared_ptr, но не разделяющий владение.

1 голос
/ 28 марта 2010

Если причина использования набора состоит в том, что вам нужно эффективно найти указатели типа T, то очевидный ответ не состоит в том, чтобы сделать его набором общих указателей! Вместо этого поместите набор в класс, который управляет временем жизни указателей, содержащихся в наборе.

...