带有transform的for_each的意外行为

时间:2013-08-01 23:35:20

标签: c++

当我用std :: transform取消注释注释行时,上面的for_each将不会打印任何内容。下面的for_each也不会打印任何内容。我认为代码将从v中获取元素,增加它们并将它们插入到v2中。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void print(const int& what){
    cout<<what<<" ";
}

int change(const int& from){
    return from+1;
}

int main() {
    vector<int> v(5,10);
    vector<int> v2;

    for_each(v.begin(),v.end(),print);
    //transform(v.begin(),v.end(),v2.begin(),change);
    for_each(v2.begin(),v2.end(),print);

    return 0;
}

2 个答案:

答案 0 :(得分:3)

std::transform的目标范围必须足够大才能保存结果。您的v2是一个空向量。您可以在致电v2.resize()之前致电std::transform或使用back_inserter,如下所示:

transform(v.begin(),v.end(),back_inserter(v2),change);

答案 1 :(得分:3)

你的第二个集合是空的 - 要将项目插入其中,你需要使用std;:back_inserter:

transform(v.begin(), v.end(), back_inserter(v2), change);

但请注意,for_each并非真正的最佳选择。如果您要使用标准算法,我建议您复制到ostream_iterator

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
transform(v.begin(), v.end(), back_inserter(v2));
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

如果您真正想要做的就是在输入中的每个项目中添加一个,您可能会发现使用std::plus之类的内容更容易,而不是为自己编写代码(或者,如果您有C ++ 11可用,你可以使用lambda)。

回答你实际问过的问题(为什么当你执行transform时,它没有真正起作用):你有未定义的行为试图访问其当前边界之外的向量。因此,允许任何行为。在UB实际被调用之前,通常有点难以看到程序中的UB 以后如何影响代码行为,但标准在允许它时非常明确。一些编译器利用这一点来实现(例如)不会(或可能不是)可能的优化。