2010-06-28 4 views
10

현재 작업중인 게임에서 플레이어의 움직임 기록을 인쇄하려고합니다. 각 라운드가 끝날 때마다 모든 플레이어는 양수 또는 음수 방향으로 약간의 양을 이동했으며 이것은 이동 벡터에 int로 기록됩니다. 결국 나는 각 플레이어의 이동 시간 대 이동 방향을 계획하고 싶지만 2d 벡터에서 데이터를 추출하는 데 문제가 있습니다.2 차원 STL 벡터 반복 C++

그래서 난 그냥 반복하고 모든 요소를 ​​인쇄하는 것이었다 시도 우선, 그러나이 컴파일되지 않습니다 :

void output_movement(const std::vector< std::vector<int> > & movement){ 

    std::vector< std::vector<int> >::iterator row; 
    std::vector<int>::iterator col; 
    for (row = movement.begin(); row != movement.end(); ++row) { 
     for (col = row->begin(); col != row->end(); ++col) { 
      std::cout << **col; 
     } 
    } 

} 

을 컴파일러는 정말하지 않습니다 이해이 오류 메시지 제공 :

hg_competition.cpp:45: error: no match for ‘operator=’ in ‘row = ((const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >*)money_movement)->std::vector<_Tp, _Alloc>::begin [with _Tp = std::vector<int, std::allocator<int> >, _Alloc = std::allocator<std::vector<int, std::allocator<int> > >]()’ 
/usr/include/c++/4.4/bits/stl_iterator.h:669: note: candidates are: __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >& __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >::operator=(const __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >&) 

도움을 주시면 대단히 감사하겠습니다.

답변

14

당신은 vector가 const를 참조 인 경우 const_iterator를 사용해야합니다. 또한 col을 출력하려면 한 번 참조 해제해야합니다.

void output_movement(const std::vector< std::vector<int> > & movement){ 

    std::vector< std::vector<int> >::const_iterator row; 
    std::vector<int>::const_iterator col; 
    for (row = movement.begin(); row != movement.end(); ++row) { 
     for (col = row->begin(); col != row->end(); ++col) { 
      std::cout << *col; 
     } 
    } 
} 

편집 : 사용 형식 정의는

typedef std::vector<int> Vector; 
typedef std::vector<Vector> DoubleVector; 

void output_movement(
    const DoubleVector& movement 
) 
{ 
    for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) { 
     for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) { 
      std::cout << *col; 
     } 
     std::cout << std::endl; 
    } 
} 
+1

나는 만약 당신이 다시 쓰려고한다면 e 코드를 사용한다면 적절한 범위 지정을 위해'for' 루프 내에'row'와'col' 선언을 적절하게 넣는 것도 가치가 있습니다. –

+0

또한 아마도'output_movement'가'operator <<'처럼 불려지는 것처럼 C++이 될 것입니다. – Philipp

+0

@Matthieu 귀하의 제안을 포함하도록 답변을 업데이트했습니다. –

4

const 개체는 const_iterators을 반환하므로 iteratorconst_iterator으로 대체하십시오. 이는 또한 벡터의 원치 않는 수정을 방지합니다.

이 샘의와 매튜의 제안의 조합은 다음과 같습니다

#include <ostream> 
#include <vector> 

typedef std::vector<int> Vector; 
typedef std::vector<Vector> DoubleVector; 


template<typename Char, typename Traits> 
std::basic_ostream<Char, Traits>& 
operator<<(std::basic_ostream<Char, Traits>& stream, 
      const DoubleVector& movement) { 
    for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) { 
     for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) { 
      stream << *col; 
     } 
    } 
return stream; 
} 
12

당신이 const_iterator 대신 iterator를 사용해야하므로 2D vector는, const를 선언된다.

또한 col을 이중 참조하지 않아야합니다. iterator이기 때문에 한 번 참조하기 만하면됩니다.

void output_movement(const std::vector< std::vector<int> > & movement){ 

    std::vector< std::vector<int> >::const_iterator row; 
    std::vector<int>::const_iterator col; 
    for (row = movement.begin(); row != movement.end(); ++row) { 
     for (col = row->begin(); col != row->end(); ++col) { 
      std::cout << *col; 
     } 
    } 

} 
0

OMG는, 아무것도for 루프의 혼란보다 더 나은 코드를 읽기 쉽게 만들 것입니다. 여기 몇 가지 대안. 원하는대로 선택하십시오.

void output_movement (const VVI & m) { 
    for_each (m.begin(), m.end(), [](const VI& v){ 
       for_each (v.begin(), v.end(), [](int i){ cout << i; }); 
       }); 
} 

나, 내 개인적인 취향 (부스트/foreach.hpp)

,

void output_movement (const VVI & m) { 
    foreach (const VI& v, m) 
     foreach (int i, v) 
      cout << i; 
} 
3

존, 당신은 C++ (11)는 람다를 사용하는 것을 제안하지만, 경우

typedef vector<int> VI; 
typedef vector<VI> VVI; 


namespace std { 
    ostream& operator<<(ostream& o, const VI& v) { 
     copy (v.begin(), v.end(), ostream_iterator<int>(cout)); 
     return o; 
    } 
} 
void output_movement (const VVI& m) { 
    copy (m.begin(), m.end(), ostream_iterator<const VI&>(cout)); 
} 

또는, 사용 가능, 필자가 선호한다

for (auto& row : movement) { 
    for (auto& elem : row) { 
     std::cout << elem; 
    } 
} 
+0

깨끗한 범위 기반 루프의 경우 +1입니다. '&'를 사용할 필요는 없지만 그렇습니까? –

+0

기독교 : 예, 있습니다! 그렇지 않으면 각 행이 복사되고 반복됩니다. 두 번째 참조는 그다지 중요하지 않습니다. – Petter

+0

벤 : 오, 그건 : 예, 물론입니다. 하지만 '행 자동'을 쓰면 실수로'행'또는'elem'을 변경하지 않을 수 있습니다. –