Вопрос

Я приезжаю на C ++ из Java и имею общую конструкторскую ситуацию, в которой у меня есть элемент (не примитивный), который я хотел бы удалить из STD :: Vector.

В Java я бы написал что-то вроде: ArrayList.Remove (ArrayList.indexof (MyClassInstance));

В C ++, с std :: вектор, какой самый лучший / самый исполнительный / самый чистый способ сделать это?

Лучшее, что я могу придумать, это создать ссылку на экземпляр, который я ищу, а затем итерации через вектор, пока не найду эту ссылку. По сути, сравнивать адрес памяти каждого элемента в векторе со ссылкой, пока не получишь совпадение.

Я на правильном пути? Или есть лучший способ сделать это? (Возможно, используя другой контейнер STD, я использовал только STD :: Vector до сих пор.)

Это было полезно?

Решение

#include <algorithm>

std::vector<Foo>::iterator it = std::find(vec.begin(), vec.end(), foo_2b_found);
if (it != vec.end()) vec.erase(it);

Другие советы

Использовать std::find найти элемент и vector::erase удалить его.

std::find По сути, итерации через вектор, чтобы найти элемент, и вы не можете сделать лучше с простом вектором (то же самое относится к случаю с Java ArrayList). Следует ли вы использовать другой контейнер, зависит от ваших требований.

Если вы хотите искать линейно через вектор, то

seq.erase( std::find( seq.begin(), seq.end(), elt ));

Если у вас есть предикат и хотите удалить все элементы, которые соответствуют предикату, то:

seq.erase( std::remove_if( seq.begin(), seq.end(), Pred ), seq.end());

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

Использование STD :: Список обратится к последнему из них: поиск будет линейным, но стирание будет постоянным временем.

Если можно хранить свои элементы в ассоциативный контейнер, который использует ключ поиска, то это было бы более эффективно: o (log n) поиск и постоянное удаление времени.

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

Для того, что вы предлагаете, то есть стирание по указателю объекта, вы можете использовать STD :: Набор для вашего типа T. Тогда используйте mySet.erase( pt ); где PT - ваш указатель. Конечно, вам нужно управлять сроком службы ваших указателей, но тот факт, который вы знаете, какой из них из вашей коллекции, предполагает, что у вас есть копия ее в другом месте.

Вы можете использовать STD :: Set, SharedPtrless>

Где вы определяете ShareDPtrless следующим образом:

template< typename T >
struct SharedPtrLess
{
   bool operator()( boost::shared_ptr<T> left, boost::shared_ptr<T> right ) const
   {
     return std::less<T>()( left.get(), right.get());
   }
};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top