2013-02-22 12 views
31

Próbuję zrobić foreach na wektorze ataków, każdy atak ma unikalny identyfikator powiedzieć, 1-3.C++ dla każdego, ciągnięcie z elementów wektorowych

Metoda klasy przyjmuje wartość z klawiatury 1-3.

Próbuję użyć foreach, aby przejść przez moje elementy w m_attack, aby sprawdzić, czy liczba pasuje, czy to ... zrób coś.

Problem widzę to:

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

będę o tym całkowicie błędne, mam C# Doświadczenie i niby co mam to na oparcie, każda pomoc będzie mile widziane.

Mój kod wygląda następująco:

W nagłówku

vector<Attack> m_attack; 

w klasie

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

Możesz użyć funkcji [std :: for_each] (http://www.cplusplus.com/reference/algorithm/for_each/) – andre

Odpowiedz

80

Dla kolejnych przykładów założono, że używasz C++ 11. Przykład dystansową opartej na pętlach:

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

Należy użyć const auto &attack w zależności od zachowania makeDamage().

Można użyć std::for_each z biblioteki standardowej + lambdas:

std::for_each(m_attack.begin(), m_attack.end(), 
     [](Attack * attack) 
     { 
      if (attack->m_num == input) 
      { 
       attack->makeDamage(); 
      } 
     } 
); 

Jeśli są niewygodne przy użyciu std::for_each można pętli nad m_attack wykorzystujące iteratory:

for (auto attack = m_attack.begin(); attack != m_attack.end(); ++attack) 
{ 
    if (attack->m_num == input) 
    { 
     attack->makeDamage(); 
    } 
} 

Zastosowanie m_attack.cbegin() i m_attack.cend() dostać const iteratory.

+1

Ah, to nagłówek, który miałem szukając wtedy, szukałem bibliotek dla niego. Dzięki. – Springfox

+0

Ten drugi jest po prostu tym, nad czym właściwie się zajmuję, a co ważniejsze rozumiem;). Dzięki za to, to jest gotowe. – Springfox

+0

@Justin Shrake: Może chcieć wyjaśnić, dlaczego przekazywanie przez odniesienie jest prawdopodobnie (ale nie zawsze) lepsze w zakresie dla pętli, w przeciwieństwie do przekazywania przez kopiowanie. – DavidO

16

ten sposób będzie się to odbywać w pętli w C++ (11):

for (const auto& attack : m_attack) 
    { 
     if (attack->m_num == input) 
     { 
      attack->makeDamage(); 
     } 
    } 

Nie ma for each w C++. Inną opcją jest użycie std::for_each z odpowiednim funktorem (może to być cokolwiek, co można nazwać argumentem jako Attack*).

+0

["dla każdego"] (http://blogs.msdn.com/ b/arich/archive/2004/09/08/227139.aspx) jest obsługiwanym rozszerzeniem w rodzimym języku VS C++ –

+0

+1 dla C++ 11 i auto – sotrh

4

C++ nie ma funkcji pętli for_each w swojej składni. Musisz użyć C++ 11 lub użyć funkcji szablonu std::for_each.

+0

Jest to pomocna dzięki, prawie już działa, ale Muszę sprawić, aby zwrócił int metody. Próbuję, próbowałem, ale nie mogę wymyślić, jak wykonać odnośnik w odpowiednim miejscu po powrocie, czy mógłbyś edytować odpowiedź, by pomóc w tym? – Springfox

+0

@Springfox W razie potrzeby możesz dodać dodatkowe zmienne składowe i uzyskać do nich dostęp później za pomocą f.method (...); – andre

+0

dlaczego nie std :: begin/std :: end on m_attack? – paulm

4

Składnia for each jest obsługiwana jako rozszerzenie natywnego języka C++ w Visual Studio.

Przykład przewidziane w 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; 
} 

(działa w VS2013) nie jest przenośna platforma/cross ale daje wyobrażenie o tym, jak używać for each.

Standardowe alternatywy (podane w pozostałych odpowiedziach) obowiązują wszędzie. I najlepiej byłoby z nich skorzystać.

Powiązane problemy