每个循环的 C++ 向量不会遍历引用?

c++ vector for each loop doesn't iterate through references?

昨天我几乎花了一个小时来调试这个东西,从那时起我就无法停止思考 it.C

我尝试用字符串索引实现一个二维矩阵...

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 each 循环更改为正常循环,例如

for (int i = 0; i < m_vect.size(); i++){
     m_vect[i].push_back(m_default);

该程序运行良好...

那么这是否意味着 v 不是引用,而是元素的新副本?

谢谢 (代码可能有错别字,我写在phone...)

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){
   //...
}
for (auto v : m_vect)
    v.push_back(m_default);

在上面的形式中,range-for 循环使用存储在 m_vect.[=18= 中的项目的 (v) 进行迭代]

如果你想直接对 references 操作 m_vect 中的项目,你应该明确说明,使用 auto&:

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

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

代码:

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