[英]Efficient std::vector initialization with another vector and map function
我有一个关于 std::vector 初始化的问题,但找不到简单的解决方案。
想象一下,我们有一个包含一些数据的向量和一个映射函数,它应该应用于这个向量的每个元素,并且这些新值应该被推回到另一个向量。
std::vector<int> vector1{10, 20, 30};
auto map = [](int v) { return v * 2; } // double each value
std::vector<int> vector2{...} // there should be 20, 40, 60 as a result
看起来容易吗? 但我想以 100% 的效率做到这一点:
输出向量应在插入前调整为输入向量大小(重复 push_back 每次都会检查向量容量,这是低效的)
在使用映射元素初始化之前,不应该对新矢量数据进行零初始化。 例如, vector::resize 会将新向量初始化为零,我想将其设为无效。
我有一个使用自定义迭代器的解决方案,反汇编看起来很高效。 但也许我错过了一些东西并且存在一些标准解决方案。
您可以使用reserve
这仅仅保留容量,但不构建元素。 要将一个向量转换为另一个向量,您可以将std::transform
与std::back_inserter
:
#include<vector>
#include<algorithm>
#include <iostream>
#include <iterator>
int main()
{
std::vector<int> vector1{10, 20, 30};
auto map = [](int v) { return v * 2; }; // double each value
std::vector<int> vector2; // there should be 20, 40, 60 as a result
vector2.reserve(vector1.size());
std::transform(vector1.begin(),vector1.end(),std::back_inserter(vector2),map);
for (const auto& e : vector2) std::cout << e << " ";
}
我不确定使用emplace
而不是back_inserter
是否会更有效。 不幸的是没有像back_emplacer
那样的back_emplacer
,所以你需要编写一个手动循环。 对于int
s,它肯定不会有什么不同。
您可以只创建具有给定大小的vector2
,然后用std::transform
填充它。
如果您不再使用vector1
,也可以重用它。
https://godbolt.org/z/GsroG1WeG
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vector1{10, 20, 30};
std::vector<int> vector2(vector1.size());
std::transform(cbegin(vector1), cend(vector1), begin(vector2), [](auto n){ return n*2; });
std::copy(cbegin(vector2), cend(vector2), std::ostream_iterator<int>(std::cout, " "));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.