迭代二维 STL 向量 c++

发布于 2024-09-07 19:49:29 字数 1873 浏览 0 评论 0原文

我目前正在尝试打印我正在开发的游戏中玩家的动作历史记录。在每轮结束时,每个玩家都在正向或负向移动了一定的量,这会被记录为移动向量中的 int 。最终我想绘制每个玩家的移动方向与时间的关系,但我在从二维向量中提取数据时遇到了困难。

所以我尝试的第一件事就是迭代并打印所有元素,但这不会编译:

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> > > > >&)

非常感谢任何帮助!

I'm currently trying to print out a history of movements for players in a game I am working on. At the end of each round every player has moved some amount in the positive or negative direction and this gets recorded as an int in the movement vector. Eventually I'm wanting to plot the directions moved vs time for each player but I'm having trouble extracting the data out of the 2d vector.

So the first thing I tried was to just iterate and print all the elements, however this doesn't compile:

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

}

The compiler gives this error message which I don't really understand:

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> > > > >&)

Any help is greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北城挽邺 2024-09-14 19:49:29

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

You need to use a const_iterator if the vector is a const reference. Also, to output col you only need to dereference it once.

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

Edit: using typedefs will make your code more readable

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;
    }
}
青巷忧颜 2024-09-14 19:49:29

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

} 

The 2D vector is declared const, so you need to use const_iterator instead of iterator.

You also shouldn't doubly dereference col. It is an iterator, so you only need to dereference once.

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

} 
玻璃人 2024-09-14 19:49:29

const 对象返回 const_iterators,因此只需将所有地方的 iterator 替换为 const_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;
}

const objects return const_iterators, so simply replace iterator by const_iterator everywhere. This also prevents unwanted modifications of the vectors.

This is the combination of Sam's and Mathieu's suggestions:

#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;
}
空气里的味道 2024-09-14 19:49:29

John,您建议使用 lambda,但如果 C++11 可用,我更喜欢

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

John, you suggested using lambdas, but if C++11 is available, I'd prefer

for (auto& row : movement) {
     for (auto& elem : row) {
        std::cout << elem;
     }
}
醉态萌生 2024-09-14 19:49:29

天哪,任何东西都比那些混乱的 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;
}

Omg, anything is better than that mess of for loops. Here some alternatives. Choose whichever you like.

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

or,

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

or, my personal preference (boost/foreach.hpp),

void output_movement (const VVI & m) {
    foreach (const VI& v, m)
        foreach (int i, v)
            cout << i;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文