Я в настоящее время пытаюсь распечатать историю перемещений за плееры в игре, я продолжаю работать. В конце каждого раунда каждый плеер переместил некоторую сумму в положительное или отрицательное направление, и это зарегистрировано как интервал в векторе перемещения. В конечном счете я желаю вывести на печать направления, перемещенные по сравнению со временем для каждого плеера, но я испытываю затруднения при извлечении данных из 2-го вектора.
Таким образом, первая вещь, которую я попробовал, состояла в том, чтобы просто выполнить итерации и распечатать все элементы, однако это не компилирует:
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> > > > >&)
Любая справка значительно ценится!
Вам необходимо использовать 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;
}
}
}
Изменить: использование typedefs сделает ваш код более читаемым
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 вектор
объявлен 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 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;
}
const
объекты возвращают const_iterators
, поэтому просто замените iterator
на const_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;
}