В каком-то классе у меня есть hash_set
из указателей:
std::hash_set<GameObject*> gameObjects;
Я хочу перебрать их все и вызвать обновление. С итераторами это было бы так:
for(std::hash_set<GameObject*>::iterator it = gameObjects.begin(), it_end = gameObjects.end(); it != it_end; ++it)
{
(*it)->update();
}
Это слишком много кода; Я хочу использовать std::for_each
,
Если бы я только что hash_set<GameObject>
это будет выглядеть так:
std::for_each(gameObjects.begin(), gameObjects.end(), std::mem_fun_ref(&GameObject::update));
или, если обновление ожидало параметр,
std::for_each(gameObjects.begin(), gameObject.end(), std::bind2nd(std::mem_fun_ref(&GameObject::update), deltaTime));
Как бы оба эти выражения выглядели для hash_set
указателей?
Я использую MS VisualStudio 2010.
Вы можете использовать тот же код, что и у вас, но использовать mem_fun
вместо mem_fun_ref
std::for_each(gameObjects.begin(), gameObjects.end(),
std::mem_fun(&GameObject::update));
Если у вас есть компилятор, который поддерживает лямбда-выражения (C ++ 11), вы можете использовать
std::for_each(gameObjects.begin(), gameObjects.end(), [=](GameObject* o) {o->update(deltaTime);});
Использование лямбда-символов является хорошим вариантом для многих алгоритмов STL, но, как указывает @phresnel, основанный на диапазоне цикл for (также C ++ 11) является более кратким в этом случае:
for (auto o : gameObjects)
o->update(deltaTime);
В качестве альтернативы std::for_each
, если ваш компилятор и политика это позволяют, вы можете использовать C ++ ‘ диапазон основан на:
for (auto p : gameObjects) p->update();
Эта функция была добавлена в C ++ 11, который является текущим стандартом C ++. Не все компиляторы (-versions) могут его поддерживать.