【问题标题】:flatten vectors in a map展平地图中的向量
【发布时间】:2015-04-18 16:52:20
【问题描述】:

在 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,当我尝试在map 中使用std::movevector 时会发生什么?

我的第二个版本是使用:

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

我想这就是我打算做的。

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

【问题讨论】:

    标签: c++11 dictionary vector constants


    【解决方案1】:

    不要使用 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 参数不必是 const。复制/移动没有区别。

    【讨论】:

      【解决方案2】:

      有一个“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 不会将其转换为可移动类型。

      【讨论】:

        猜你喜欢
        • 2019-02-09
        • 1970-01-01
        • 2019-09-06
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2021-07-02
        • 1970-01-01
        • 2021-06-01
        相关资源
        最近更新 更多