Форум программистов, компьютерный форум CyberForum.ru

Удаление элемента из вектора ( std::vector<Bullet> ) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
NanoBreaker
 Аватар для NanoBreaker
23 / 23 / 7
Регистрация: 11.07.2013
Сообщений: 82
27.07.2013, 20:29     Удаление элемента из вектора ( std::vector<Bullet> ) #1
Здравствуйте!
У меня возникла проблема во время удаления элементов, значения которых не удовлетворяли условию.

П.С: До того как создавать тему, я пошастал по форуму, но так и не нашел похожей проблемы и её решения, поэтому и создал это тему.

Есть следующие файлы:
Main.cpp
Bullet.hpp
Bullet.cpp

(В глубину кода можете не вдоваться, рисую пули в OpenGL, в координатной оси с осями от -250 до 250, и приходиться производить дополнительные вычисления для перевода координат пуль из одной системы координат в другую)

Main.cpp(выделил нужный кусок кода):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Bullet.hpp"
 
vector<Bullet> bullets;
 
. . . .
 
for(auto iter = bullets.begin(); iter != bullets.end(); iter++)
{
    if( iter -> x > 250 || iter -> x < -250 || iter -> y > 250 || iter -> y < -250 ){
        bullets.erase(iter);
    }else{
        iter -> moveBullet();
    }
}

Bullet.hpp:

C++
1
2
3
4
5
6
7
8
9
10
11
struct Bullet{
 
    double x;
    double y;
    double k;
 
    bool isXnegative;
 
    void initBullet(double _x, double _y);
    void moveBullet();
};
Bullet.cpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "Bullet.hpp"
 
void Bullet::initBullet(double _x, double _y)
{
    _x = _x - 250;
    _y = 250 -_y;
    k = _y / _x;
 
    if(_x < 0) isXnegative = true; else isXnegative = false;
 
    x = 0;
    y = 0;
}
 
void Bullet::moveBullet()
{
    if(isXnegative){
        x -= 0.5;
    }else{
        x += 0.5;
    }
    y = k * x;
}
Когда пуля выходит за допустимое значение, то есть не удовлетворяет условию из main.cpp, она должна удалиться.
Но я получаю следующую ошибку: "Expression: vector iterator not incrementable"

В интернете не мало времени потратил на поиск решения этой проблемы, уже понял что так удалять нельзя, и за собой ещё надо удалять этот итератор, но когда я делаю
C++
1
vector<Bullet*>::iterator iter = bullets.begin();
чтоб в дальнейшем удалить и итератор, он мне говорит, что:

IntelliSense: no suitable user-defined conversion from "std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Bullet>>>" to "std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Bullet *>>>" exists c:\Users\NanoBreaker\Documents\Visual Studio 2012\Projects\Bullet's trajectory\Bullet's trajectory\Main.cpp 53

Более чем уверен что, решение этой проблемы довольно простое, но увы я не могу его найти.
Спасибо за последующие ответы.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.07.2013, 20:29     Удаление элемента из вектора ( std::vector<Bullet> )
Посмотрите здесь:

Обращение к полю элемента std::vector'a C++
C++ Удаление элемента из vector
Удаление элементов из std::vector C++
Вывести значения std::vector<std::vector<int*> > C++
Удаление элемента из std::vector<> C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
27.07.2013, 20:38     Удаление элемента из вектора ( std::vector<Bullet> ) #2
Цитата Сообщение от NanoBreaker Посмотреть сообщение
for(auto iter = bullets.begin(); iter != bullets.end(); iter++) { if( iter -> x > 250 || iter -> x < -250 || iter -> y > 250 || iter -> y < -250 ){ bullets.erase(iter); }else{ iter -> moveBullet(); } }
C++
1
2
3
4
5
6
7
8
for (auto iter = bullets.begin(); iter != bullets.end(); ) {
   if (/* ... */) {
      iter = bullets.erase(iter);
   } else {
      iter->moveBullet();
      ++iter;
   }
}
Добавлено через 56 секунд
Просто после erase(iter) iter становиться невалидным.

Добавлено через 3 минуты
вообще как то так
C++
1
2
3
4
5
6
bullets.erase(
      std::remove_if(std::begin(bullets), std::end(bullets), [] (Bullet const& bullet) {
            return (bullet.x > 250 || bullet.x < -250 || bullet.y > 250 || bullet.y < -250);
      })
    , std::end(bullets));
std::for_each(std::begin(bullets), std::end(bullets), std::mem_fn(&Bullet::moveBullet));
NanoBreaker
 Аватар для NanoBreaker
23 / 23 / 7
Регистрация: 11.07.2013
Сообщений: 82
27.07.2013, 20:42  [ТС]     Удаление элемента из вектора ( std::vector<Bullet> ) #3
Спасибо, теперь всё работает.

Добавлено через 1 минуту

Хм, второй вариант выглядит красиво, + это ты там лямбду используешь?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
27.07.2013, 20:44     Удаление элемента из вектора ( std::vector<Bullet> ) #4
Цитата Сообщение от NanoBreaker Посмотреть сообщение
ты там лямбду используешь?
Да, можно отдельно лямбду\функцию\метод\функтор написать, если не один раз используется.
NanoBreaker
 Аватар для NanoBreaker
23 / 23 / 7
Регистрация: 11.07.2013
Сообщений: 82
27.07.2013, 20:47  [ТС]     Удаление элемента из вектора ( std::vector<Bullet> ) #5
Ещё раз спасибо, вопрос исчерпан. Не первый раз ты мне помогаешь )
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
27.07.2013, 20:47     Удаление элемента из вектора ( std::vector<Bullet> ) #6
Цитата Сообщение от NanoBreaker Посмотреть сообщение
Хм, второй вариант выглядит красиво
Ну я бы предпочёл что-нибудь менее громоздкое, хотя бы так:
C++
1
2
bullets.erase(boost::remove_if(bullets, [] (Bullet const& bullet) { return /* ... */}), std::end(bullets));
boost::for_each(bullets, std::mem_fn(&Bullets::moveBullet));
Yandex
Объявления
27.07.2013, 20:47     Удаление элемента из вектора ( std::vector<Bullet> )
Ответ Создать тему
Опции темы

Текущее время: 02:08. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru