[英]Iterating over 2-dimensional STL vector c++
我正在嘗試打印我正在制作的游戲中玩家的動作歷史。 在每輪結束時,每個玩家都在正方向或負方向上移動了一些數量,並將其記錄為運動矢量中的int。 最終我想要為每個玩家繪制移動方向與時間的關系,但是我無法從2d向量中提取數據。
所以我嘗試的第一件事就是迭代並打印所有元素,但是這不能編譯:
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> > > > >&)
任何幫助是極大的贊賞!
如果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將使您的代碼更具可讀性
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;
}
}
2D vector
聲明為const
,因此您需要使用const_iterator
而不是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;
}
}
}
const
對象返回const_iterators
,因此只需用const_iterator
替換iterator
。 這也可以防止不需要的載體修飾。
這是Sam和Mathieu的建議的結合:
#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;
}
約翰,你建議使用lambdas,但如果C ++ 11可用,我更喜歡
for (auto& row : movement) {
for (auto& elem : row) {
std::cout << elem;
}
}
媽呀, 什么是比那些亂七八糟更好for
循環。 這里有一些選擇。 選擇你喜歡的任何一個。
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));
}
要么,
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; });
});
}
或者,我個人的偏好(boost / foreach.hpp),
void output_movement (const VVI & m) {
foreach (const VI& v, m)
foreach (int i, v)
cout << i;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.