C++ for each, pulling from vector elements
Solution 1
For next examples assumed that you use C++11. Example with ranged-based for loops:
for (auto &attack : m_attack) // access by reference to avoid copying
{
if (attack->m_num == input)
{
attack->makeDamage();
}
}
You should use const auto &attack
depending on the behavior of makeDamage()
.
You can use std::for_each
from standard library + lambdas:
std::for_each(m_attack.begin(), m_attack.end(),
[](Attack * attack)
{
if (attack->m_num == input)
{
attack->makeDamage();
}
}
);
If you are uncomfortable using std::for_each
, you can loop over m_attack
using iterators:
for (auto attack = m_attack.begin(); attack != m_attack.end(); ++attack)
{
if (attack->m_num == input)
{
attack->makeDamage();
}
}
Use m_attack.cbegin()
and m_attack.cend()
to get const
iterators.
Solution 2
This is how it would be done in a loop in C++(11):
for (const auto& attack : m_attack)
{
if (attack->m_num == input)
{
attack->makeDamage();
}
}
There is no for each
in C++. Another option is to use std::for_each with a suitable functor (this could be anything that can be called with an Attack*
as argument).
Solution 3
The for each
syntax is supported as an extension to native c++ in Visual Studio.
The example provided in msdn
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int total = 0;
vector<int> v(6);
v[0] = 10; v[1] = 20; v[2] = 30;
v[3] = 40; v[4] = 50; v[5] = 60;
for each(int i in v) {
total += i;
}
cout << total << endl;
}
(works in VS2013) is not portable/cross platform but gives you an idea of how to use for each
.
The standard alternatives (provided in the rest of the answers) apply everywhere. And it would be best to use those.
Solution 4
C++ does not have the for_each
loop feature in its syntax. You have to use c++11 or use the template function std::for_each
.
struct Function {
int input;
Function(int input): input(input) {}
void operator()(Attack& attack) {
if(attack->m_num == input) attack->makeDamage();
}
};
Function f(input);
std::for_each(m_attack.begin(), m_attack.end(), f);
Related videos on Youtube
Springfox
Updated on October 02, 2020Comments
-
Springfox over 3 years
I am trying to do a foreach on a vector of attacks, each attack has a unique ID say, 1-3.
The class method takes the keyboard input of 1-3.
I am trying to use a foreach to run through my elements in m_attack to see if the number matches, if it does... do something.
The problem I'm seeing is this:
a'for each' statement cannot operate on an expression of type "std::vector<Attack
Am I going about this totally wrong, I have C# experience and is kind of what I'm basing this on, any help would be appreciated.
My code is as follows:
In header
vector<Attack> m_attack;
In class
int Player::useAttack (int input) { for each (Attack* attack in m_attack) // Problem part { //Psuedo for following action if (attack->m_num == input) { //For the found attack, do it's damage attack->makeDamage(); } } }
-
andre about 11 yearsYou can use the function std::for_each
-
cprn about 3 yearsA different approach but:
std::map<int, Attack*> attacks;
and in method:attacks[input]->makeDamage();
(in try catch forout_of_range
exception).
-
-
Springfox about 11 yearsAh, that's the header I was searching for then, I was hunting libraries for it. Thanks.
-
Springfox about 11 yearsThis is such a help thanks, I've almost got it working but I need to make it return an int for the method. I'm trying, I have tried but can't work out how to do reference the pointer in the correct place on a return, could you possibly edit your answer to help with that?
-
andre about 11 years@Springfox You can add extra member variables to the struct if needed and access them later using f.method(...);
-
Springfox about 11 yearsThat second one is just what I'm after actually, and more importantly I understand ;). Thanks for that, that's got it.
-
DavidO about 11 years@Justin Shrake : May want to explain why pass by reference is probably (but not always) preferable in ranged for loops, as opposed to pass by copy.
-
paulm about 10 yearswhy not std::begin/std::end on m_attack?
-
Nikos Athanasiou about 10 years
for each
is a supported extension in VS's native c++ -
Nikos Athanasiou about 10 years
for each
is a supported extension in VS's native c++ -
Nubcake over 6 yearsI'm brushing up on my C++ so if you use a reference, it avoids copying the object in question? What about a pointer?
-
odalet about 6 yearsIn your first example, doesn't
auto& attack
impliesattack.m_num
andattack.makeDamage()
instead of the arrow notation?