我向你介绍我的问题
我有 2 个列表,分别命名为 A 和 B。
list<vector<int> > A = {{1},{2},{3}};
list<vector<int> > B = {{4},{5},{6}};
我想要的是 A = {{1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3 ,4},{3,5},{3,6}} 不使用任何 tmp 列表。
我在 Ubuntu 12.04 上使用 C++11 和 gcc 4.6.3
这样最小化代码:
auto A_begin = A.begin();
auto A_end = A.end();
auto B_begin = B.begin();
auto B_end = B.end();
for(auto i = A_begin; i != A_end; ++i) //loop on A
{
for (auto j = B_begin;j != B_end; ++j) //loop on B
{
vector<int> tmp = (*i); // A[i]
copy((*j).begin(),(*j).end(),back_inserter(tmp)); // append B[j] to A[i]
A.emplace_back(tmp); //add it to A
}
}
A.erase(A_begin,A_end); // remove {1},{2},{3}
所以,我认为这个算法没问题,但是它在 A 上造成了无限循环。 我认为当我制作 A.emplace_back 时 A_end 会发生变化,但我保存了它,所以我真的不知道在这里附加什么。
我的代码来识别问题:
auto A_begin = A.begin();
auto A_end = A.end();
auto B_begin = B.begin();
auto B_end = B.end();
int ii = A.size();
for(auto i = A_begin; i != A_end; ++i) //loop on A
{
for (auto j = B_begin;j != B_end; ++j) //loop on B
{
vector<int> tmp = (*i);
A.emplace_back(tmp);
}
cout<<--ii<<endl; // exit when print 0 ?
}
这会打印负数,我必须再次^C。
编辑:我找到了解决方案:
auto A_begin = A.begin();
auto A_end = A.end();
auto B_begin = B.begin();
auto B_end = B.end();
list<vector<int>> tmp_l;
for(auto i = A_begin; i != A_end; ++i) //loop on A
{
for (auto j = B_begin;j != B_end; ++j) //loop on B
{
vector<int> tmp = (*i); // A[i]
copy((*j).begin(),(*j).end(),back_inserter(tmp)); // append B[j] to A[i]
tmp_l.emplace_back(move(tmp)); //add it to A
}
}
swap(tmp_l,A);
最佳答案
这两行:
vector<int> tmp = (*i); // A[i]
copy((*j).begin(),(*j).end(),tmp.end()); // append B[j] to A[i]
将调用未定义的行为。通过复制到 tmp.end(),您只是覆盖 A[i] 末尾后的内存,而不是扩展 A[i]。您需要使用 back_insert 迭代器,例如:
vector<int> tmp = (*i); // A[i]
copy((*j).begin(), (*j).end(), back_inserter(tmp)); // append B[j] to A[i]
您还需要包含 header 才能获取 back_inserter。
编辑:另外,A_end迭代器指向列表“超过末尾”的位置,因此无论您向a添加多少项,它们总是添加在A_end前面,因此无限循环。我不确定是否有好的方法来处理这个问题。不创建临时列表没有任何好处,无论哪种方式,您都分配相同的内存,只需写入新列表即可。
关于c++ - emplace_back 当循环同一列表时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14399573/