压平地图中的向量

flatten vectors in a map

在 C++ 中,我有一个 map < int, vector < double > >map < int, vector < some_Struct > >,我需要连接此映射中的向量和 return 结果。

第一版函数如下:

#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,当我尝试对 vector 使用 std::move 时会发生什么map?

我的第二个版本是使用:

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

我想这正是我想要做的。

我对 C++ 很陌生。 STL给我的感觉是python所以我想试试

如果您不想移动元素,请不要使用 make_move_iterator(Iterator),只需使用 Iterator。例如:

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

如您所料,您的第二个版本确实实现了您想要实现的目标。 关于您关于 const 映射上的 std::move 的问题,std::move 在这种情况下不会做任何事情。由于 std::move 是无条件转换为右值的,它会将元素转换为对右值的 const 引用。因为它是 const 它将匹配左值 ctor(在这种情况下是复制 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 参数不必是常量。 copy/move.

没有区别

有一个 '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 实际上并没有移动数据。它将引用强制转换为右值引用,如果非 const,则为移动构造函数可以使用的 "movable" 数据类型。但它永远不会删除 const 类型限定符,因此在 const 引用上使用 std::move 不会将其转换为可移动类型。