每个循环的 c++ 向量不会遍历引用?
Posted
技术标签:
【中文标题】每个循环的 c++ 向量不会遍历引用?【英文标题】:c++ vector for each loop doesn't iterate through references? 【发布时间】:2016-07-09 02:54:00 【问题描述】:昨天我花了几乎我们的时间来调试这个东西,从那以后我就无法停止思考它。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
不是引用,而是元素的新副本?
谢谢 (代码可能有错别字,我在手机上写的……)
【问题讨论】:
是的,没错。如果您需要参考,请尝试for (auto& v : m_vect)
。
【参考方案1】:
代码:
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);
【讨论】:
【参考方案2】:for (auto v : m_vect) v.push_back(m_default);
在上述形式中,range-for 循环使用存储在m_vect
中的项目的副本 (v
) 进行迭代。
如果您想直接对m_vect
中的项目的引用 进行操作,您应该明确说明这一点,使用auto&
:
// v references items in m_vect
for (auto& v : m_vect)
v.push_back(m_default);
你可能会觉得this *** answer on using C++11 range-for很有趣。
【讨论】:
【参考方案3】:是的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)
//...
【讨论】:
以上是关于每个循环的 c++ 向量不会遍历引用?的主要内容,如果未能解决你的问题,请参考以下文章