C++中的for each循环,从向量元素中提取数据。

95

我正在尝试在攻击向量上使用foreach循环,每个攻击都有一个唯一ID,比如1-3。

类方法会接受键盘输入的1-3。

我正在尝试使用foreach来遍历m_attack中的元素,查看数字是否匹配,如果匹配...做某些事情。

我遇到的问题是:

a'for each' statement cannot operate on an expression of type "std::vector<Attack

我这样做是完全错误的吗?我有C#的经验,这在某种程度上是我依据的,任何帮助将不胜感激。

我的代码如下:

在头部

vector<Attack> m_attack;

在课堂上
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();
        }
    }
}

2
你可以使用函数[std :: for_each](http://www.cplusplus.com/reference/algorithm/for_each/) - andre
另一种方法是:std::map<int, Attack*> attacks;,在方法中:attacks[input]->makeDamage();(在 out_of_range 异常的 try catch 中)。 - cprn
4个回答

208

假设您使用的是C++11,下面是一个涉及范围for循环的示例:

for (auto &attack : m_attack) // access by reference to avoid copying
{  
    if (attack.m_num == input)
    {
        attack.makeDamage();
    }
}

你应该根据makeDamage()的行为使用const auto &attack
你可以使用标准库中的std::for_each和lambda表达式:
std::for_each(m_attack.begin(), m_attack.end(),
        [](Attack * attack)
        {
            if (attack->m_num == input)
            {
                attack->makeDamage();
            }
        }
);

如果您不喜欢使用std::for_each,可以使用迭代器循环遍历m_attack
for (auto attack = m_attack.begin(); attack != m_attack.end(); ++attack)
{  
    if (attack->m_num == input)
    {
        attack->makeDamage();
    }
}

使用 m_attack.cbegin()m_attack.cend() 获取 const 迭代器。

1
啊,那就是我一直在找的头文件,我一直在寻找相关的库。谢谢。 - Springfox
第二个正是我需要的,更重要的是我理解了 ;)谢谢,问题解决了。 - Springfox
@Justin Shrake:在范围for循环中,为什么传递引用可能更好(但并非总是如此),而不是传递副本,请解释一下。 - DavidO
我正在复习C++,如果你使用引用,它会避免复制所讨论的对象?那指针呢? - Nubcake
3
在你的第一个例子中,auto& attack是否意味着使用点符号访问attack.m_numattack.makeDamage()而不是箭头符号? - odalet

33
这是在C++(11)中使用循环完成的方法:
   for (const auto& attack : m_attack)
    {  
        if (attack->m_num == input)
        {
            attack->makeDamage();
        }
    }

C++中没有for each循环。另一个选择是使用std::for_each和适当的函数对象(可以是任何可以接受Attack*作为参数的东西)。


6
"for each" 是 VS 原生 C++ 中的一个支持扩展。 - Nikos Athanasiou

12
< p >在Visual Studio中,for each语法是对本地C++的扩展支持。

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;
}

(适用于VS2013) 不具备可移植性/跨平台性,但能让你了解如何使用for each

标准替代方案(在其他答案中提供)适用于任何地方。最好使用它们。


6

C++语法中没有for_each循环功能。您必须使用c++11或使用模板函数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);

这真是太有帮助了,谢谢!我已经差不多搞定了,但我需要让它返回一个整数类型。我正在尝试,已经尝试过了,但是无法弄清楚如何在返回时正确地引用指针,您能否编辑您的答案来帮助解决这个问题? - Springfox
@Springfox 如果需要,您可以向结构体添加额外的成员变量,并在以后使用f.method(...)访问它们。 - andre
为什么不在m_attack上使用std::begin/std::end呢? - paulm
1
for each是VS本地C++支持的扩展。 - Nikos Athanasiou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接