在地图中展平矢量

时间:2015-04-18 16:52:21

标签: c++11 dictionary vector const

在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进行编译。

所以问题是,我宣布mapconst,当我尝试将std::move之类的内容用于vector map时会发生什么? 1}}?

我的第二个版本是使用:

copy(it->second.begin(), it->second.end(), back_inserter(records));

我想这就是我打算做的事情。

我对C ++很陌生。 STL给我一种python编码的感觉,所以我想尝试一下。

2 个答案:

答案 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不会将其转换为可移动类型。