在C ++中,我有map < int, vector < double > >
或map < int, vector < some_Struct > >
,我需要连接此映射中的向量并返回结果。
该功能的第一个版本如下:
#include <algorithm>
#include <vector>
vector < double >
flattenRecords(const map < int, vector < double > > & selected, int num_kept_reps)
{
vector < double > records;
int cnt = 0;
for (auto it = selected.begin(); it != selected.end(); ++it) {
records.insert(records.end(),
make_move_iterator(it->second.begin()),
make_move_iterator(it->second.end()));
cnt += 1;
if (cnt >= num_kept_reps)
break;
}
return records;
}
我知道这不是我打算做的,因为我希望将数据保留在map
中,因此不应使用make_move_iterator
。
代码可以使用带有-std=c++0x
标志的g ++(GCC)4.4.7进行编译。
所以问题是,我宣布map
为const
,当我尝试将std::move
之类的内容用于vector
map
时会发生什么? 1}}?
我的第二个版本是使用:
copy(it->second.begin(), it->second.end(), back_inserter(records));
我想这就是我打算做的事情。
我对C ++很陌生。 STL给我一种python编码的感觉,所以我想尝试一下。
答案 0 :(得分:3)
如果您不想移动元素,只需使用Iterator,而不是使用make_move_iterator(Iterator)。例如:
records.insert(records.end(), it->second.begin(), it->second.end());
您的第二个版本,正如您所猜测的那样,确实是您尝试实现的目标。 关于你在const地图上关于std :: move的问题,std :: move在这种情况下不会做任何事情。由于std :: move是无条件转换为rvalue,因此它将元素转换为对rvalue的const引用。因为它的常量匹配左值(本例中为copy ctor),而不是移动(复制)ctor。
例如:
const std::string s1 = "Test";
const std::string s2 = std::move(s1);
这将调用std :: string的复制构造函数,而不是移动构造函数。因此,它会复制,而不是移动。
这将采取行动:
std::string s1 = "Test";
const std::string s2 = std::move(s1);
两个示例中的s2参数不必是const。它对复制/移动没有任何区别。
答案 1 :(得分:1)
有一个'pythonic'替代方案,如果你来自Python,可能会喜欢使用lambda和“mapped-reduce”函数
std::vector<double> merged = std::accumulate(selected.begin(),
selected.end(),
std::vector<double>(),
[](const std::vector<double>& a, std::vector<double>& b)
{
std::vector<double> result(a);
std::copy(b.begin(), b.end(), std::back_inserter(result));
return result;
});
);
std::move
实际上并没有移动数据。它对r值引用进行了引用,如果是非const,则它是移动构造函数可以使用的“可移动”数据类型。但它永远不会删除const类型限定符,因此在const引用上使用std::move
不会将其转换为可移动类型。