每个循环的c ++向量不会通过引用进行迭代?

时间:2016-03-22 09:32:32

标签: c++ vector foreach reference pass-by-reference

昨天我几乎花了一个时间来调试这个东西,从那时起我就不能再考虑它.C

我尝试用字符串索引实现2D矩阵......

class CSqrMatrix(){
  ....
  void insert(string str){
     bool b = map.insert(str,m_size).second;
     if (b){
         m_size++;
         vector<int> ve;
         for (int i = 0; i < m_vect.size(); i++) 
             ve.push_back(m_default);
         m_vect.push_back(ve);
         for (auto v : m_vect)
             v.push_back(m_default);
     }
  ...
map<string,int> map;
vector < vector<int> > m_vect;
int m_default;
int m_size;
};

在一些插入之后,当我试图达到像

这样的元素时
m_vect[0][0] = 8;

我的写入和段错误无效...... m_vect[0].size()的值为0; 我尝试了一切,最后我将每个循环更改为正常的

for (int i = 0; i < m_vect.size(); i++){
     m_vect[i].push_back(m_default);
该计划运作良好......

这是否意味着,v引用了一个引用,但是该元素的新副本?

由于 (代码中可能存在拼写错误,我在手机上写了...)

3 个答案:

答案 0 :(得分:2)

v确实是副本。你应该这样做:

for (auto& v : m_vect){
   v.push_back(m_default);
}

请记住,std::vector副本是容器和所有项目的深层副本,这实际上是一项昂贵的操作。因此,如果您想要通过矢量矢量(std::vector<std::vector<T>>)进行传递,即使不进行编辑,也应该通过ref传递(如果您不想编辑,则使用const):

for(/*const*/ auto& v:vectors){
   //...
}

答案 1 :(得分:2)

for (auto v : m_vect)
    v.push_back(m_default);

在上面的表单中,range-for循环使用v中存储的项目的副本m_vect)进行迭代。

如果您希望直接对m_vect中的项目引用进行操作,则应明确使用 auto& :< / p>

// v references items in m_vect
for (auto& v : m_vect) {
    v.push_back(m_default);
}

您可能会发现this StackOverflow answer on using C++11 range-for很有趣。

答案 2 :(得分:2)

代码:

for (auto v : m_vect)
    v.push_back(m_default);

等同于以下(参见C ++标准[stmt.ranged] ):

{
    auto && __range = (m_vect);
    for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin)
    {
        auto v = *__begin;      // <-- new copy in each iteration
        v.push_back(m_default); // add item to the copy
                                // the copy goes out of scope
    }
}

所以,是的,v引用了一个引用,但每次迭代都有一个新副本?

你想要的是:

for (auto& v : m_vect)
    v.push_back(m_default);

这相当于:

{
    auto && __range = (m_vect);
    for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin)
    {
        auto& v = *__begin; // <-- new reference in each iteration
        v.push_back(m_default);
    }
}