2014-12-26 2 views
-5

У меня есть вектор:как найти и удалить элемент из вектора C++

std::vector<User*> myFriends_; 

Тогда у меня есть код, чтобы увидеть, если элемент theFriend существует в векторе.

if (std::find(myFriends_.begin(), myFriends_.end(), theFriend)!=myFriends_.end()) 
      return FAILURE; 

Я хотел бы сделать некоторые вещи, как

User* toErease; 
toErease=std::find(myFriends_.begin(), myFriends_.end(), theFriend); 
if (toErease!=myFriends_.end()) 
       return FAILURE; 
myFriends_.erase(toErease); /// remove this element if its precent 

Будет ли она работать?

find возвращает расположение элемента

И erase нуждается в индексе, насколько я знаю.

+5

https://en.wikipedia.org/wiki/Eras e-remove_idiom – Borgleader

+2

Вызов 'std :: vector :: erase' с итератором, возвращаемым' std :: find'. – juanchopanza

+0

'theFriend)! = MyFriends_.end()' не является подходящим предикатом. Поместите это в лямбда-функцию или класс функтора. Также ['remove_if()'] (http://en.cppreference.com/w/cpp/algorithm/remove) может помочь упростить. –

ответ

6
std::find(myFriends_.begin(), myFriends_.end(), theFriend); 

возвращает итератор типа std::vector<User*>::iterator

Таким образом, вы должны иметь

std::vector<User*>::iterator toErease ; 

toErease=std::find(myFriends_.begin(), myFriends_.end(), theFriend); 

// And then erase if found 
if (toErease!=myFriends_.end()) 
{ 
    /* Since container element is a pointer to User 
     you need to destroy it too ! */ 
    delete *toErease ; 

    myFriends_.erase(toErease); 
    //... return SUCCESS ; 
} 
return FAILURE ; 
1

Я думаю, что вы имеете в виду следующее

User *theFriend = new User(/*...*/); 
//... 
auto it = std::find_if(myFriends_.begin(), myFriends_.end(), 
         [&](User *user) { return *user == *theFriend; }); 

if (it != myFriends_.end()) 
{ 
    delete *it; 
    myFriends_.erase(it); 
} 

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

+0

, если OP хочет удалить элемент, 'std :: vector >' кажется более подходящим. – Jarod42

+0

@ Jarod42 Это не ответ на вопрос. Это ответ на вопрос, как лучше определить вектор указателей. –

0

Эффективная книга STL советует в своем элементе 33 p 120 знать, как удалить алгоритмы на контейнерах указателей, и рекомендовать использовать контейнеры интеллектуальных указателей вместо контейнеров с исходными указателями. Пример кода, основанного на стирании удаления идиомы для вашего дела, будет следующим.

  1. Объявить функцию, чтобы проверить наличие TheFriend в векторе и удалить его (функтор будет более уместно):

    недействительным delAndNullifyFirend (Пользователь * & pUser`) {// проверить наличие theFriends и удалить}

`

for_each(myFriends_.begin(),myFriends_.end(), delAndNullifyFirend);` 
myFriends_.erase(remove(myFriends_.begin(),myFriends_.end(),static_cast<User*>(0)), 
        myFriends_.end()); 
Смежные вопросы