Вопрос

Привет всем!Я занимаюсь этим проектом, и прямо сейчас я пытаюсь:

  1. создайте некоторые объекты и сохраните их в векторах, которые будут сохранены в другом векторе V
  2. выполните итерацию по векторам внутри V
  3. перебор объектов внутри отдельных векторов

В любом случае, я просто искал в Интернете и наткнулся на функцию stl for_each .Это кажется довольно аккуратным, но у меня с этим проблемы.Я пытаюсь использовать это таким образом:

for_each(V.begin(), V.end(), iterateThroughSmallVectors);

прохождение итерации....просто делает то же самое с переданным ему вектором..

Теперь я получаю странную ошибку времени выполнения "Несовместимые векторные итераторы".Я просмотрел его и не могу найти никакой полезной информации по этому поводу..

Я не знаю, помогает ли это, но V - это частный вектор<> хранится в классе A, у которого есть средство доступа к нему, и я пытаюсь выполнить итерацию по нему в классе B, выполнив:

A->getV().begin(), A->getV().end(), etc..

У кого-нибудь есть хоть какое-то представление о том, что происходит?

Редактировать:Хорошо, поэтому я думаю, что лучше просто опубликовать код и указать, где могут возникнуть проблемы...

getTiles в GameState.h:

vector<vector<tile*>> getTiles();

for_each циклы в main.cpp:

for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);
.
.
void drawTiles(vector<tile*> row)
{
for_each(row.begin(), row.end(), dTile);
}
void dTile(tile *t)
{
t->draw();
}        

создание векторов:

int tp = -1;
int bCounter = 0;
int wCounter = 0;
for (int i = 0; i < 8; i++)
{
vector<tile*> row(8);
    for (int j = 0; j < 8; j++)
    {
    tile *t = new tile(tp, (i+(SIDELENGTH/2))*SIDELENGTH,
        (j+(SIDELENGTH/2))*SIDELENGTH);
    row.push_back(t);
            tp *= -1;
    }
currState->setTiles(row);
    tp *= -1;
}

и на всякий случай, если это может иметь отношение к делу:

void gameState::setTiles(vector<tile*> val)
{
    tiles.push_back(val);
}

Легче ли сейчас определить проблему?Я надеюсь на это...И если вы заметите какие-нибудь глупости, которые я, возможно, делаю, пожалуйста, дайте мне знать, я вроде как новичок в C ++, и указатели и ссылки все еще сбивают меня с толку.

РЕДАКТИРОВАТЬ 2:Спасибо, ребята, это сработало отлично...что ж, что касается этой проблемы, то теперь, похоже, у меня возникла проблема с созданием плиток и построением их в вектор строк..кажется, что даже несмотря на то, что вектор создан и передается правильно, плитки, которые должны были быть в нем, таковыми не являются (они теряются после :

    for (int j = 0; j < 8; j++)
    {
    tile *t = new tile(tp, (i+(SIDELENGTH/2))*SIDELENGTH,
        (j+(SIDELENGTH/2))*SIDELENGTH);
    row.push_back(t);
            tp *= -1;
    }

петля.Если у кого-нибудь из вас есть хорошие идеи по решению этой проблемы, пожалуйста, помогите мне ;) Тем временем я буду продолжать пытаться это исправить

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

Решение

Для чего нужен прототип A::getV()?

Я только предполагаю, но если A::getV() не возвращает ссылку, тогда это может объяснить сообщение об ошибке "Векторные итераторы несовместимы".

В самом деле A->getV().begin() и A->getV().end() было бы два итератора по разным векторам:каждый A->getV() вызов, возвращающий другую копию закрытого участника.

Надеюсь, это поможет вам отладить вашу проблему.


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

vector<vector<tile*> > getTiles();

Как следствие, в следующем заявлении:

for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);

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

Кроме того, как указал Чарльз в своем подробном ответе, эти временные векторы будут уничтожены к тому времени , когда тело функции for_each достигается.

Рассмотрите возможность возврата вектора по ссылке const следующим образом:

const vector<vector<tile*> >& getTiles() const;

И ты с таким же успехом можешь измениться drawTiles чтобы избежать еще большего количества копий:

void drawTiles(const vector<tile*>& row)

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

То, что я делаю, это:прямой путь

vector<vector<int> > vvi;
vector<vector<int> >::iterator vvi_iterator;
vector<int>::iterator vi_iterator;

for(vvi_terator = vvi.begin();vvi_iterator!=vvi.end();++vvi_iterator) {
    for(vi_iterator = (*vvi_iterator).begin();vi_iterator!=(*vvi_iterator).end();++vi _iterator) {
     cout<<*vi_iterator<<" ";
    }  
}

Это приблизительная идея.Я нахожу метод for_each громоздким для простого выполнения двойного цикла.for_each полезно, когда вы действительно хотите выполнить некоторые вычисления для каждого элемента (например, какое-то отображение для каждого элемента)

У вас есть пара серьезных ошибок, но сначала одна незначительная.

vector<vector<tile*>> getTiles();

Пока не выйдет следующий стандарт, вам нужен пробел между >.

vector< vector<tile*> > getTiles();

Эта функция возвращает vector по значению, что означает, что он создает новую копию чего бы то ни было vector передается оператору return в функции.(Я предполагаю, что это объявление функции является любым классом curState является примером.)

Когда вы затем делаете:

for_each(currState->getTiles().begin(),currState->getTiles().end(), drawTiles);

Каждый вызов getTiles возвращает отдельную временную копию вектора.Это не только означает , что ваши итераторы из begin() и end() исходят из разностных векторов, но векторы будут уничтожены к тому времени, когда тело функции for_each достигается.

Похоже, вам нужно исследовать ссылки и передавать по ссылке, потому что вам нужно понять их, прежде чем вы сможете правильно использовать std::for_each в этих сценариях.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top