【问题标题】:How to move a std::vector into a raw array in C++如何将 std::vector 移动到 C++ 中的原始数组中
【发布时间】:2020-01-31 22:11:54
【问题描述】:

如何在不复制或迭代所有元素的情况下安全地将std::vector 的内容移动到数组中?

void someFunc(float* arr, std::size_t& size)
{
   std::vector<float> vec(5, 1.5f);
   // do something with the data

   size = vec.size();
   arr = vec.data(); // this doesn't work, as at the end of the function the data in std::vector will be deallocated

}

main()
{
   float* arr;
   std::size_t size{0};

   someFunc(arr, size);

   // do something with the data
   delete [] arr;
}

如何将std::vector 中的数据分配给我的数组,并确保不会在std::vector 上调用解除分配?或者有什么其他想法可以解决这个问题?

【问题讨论】:

  • 你的目标是什么?为什么不保留向量并使用它的.data()
  • @BoboFeugo -- 但是你只需要将data() 传递给顶层的“旧代码”函数,剩下的都是一个数组,旧代码不知道数据是由向量管理。你用过data()吗?
  • @BoboFeugo only from a const vector。从可变向量中,您得到一个指向可变的指针
  • @PaulMcKenzie 或free(),或delete,或lib_MyBadOlLib_Free()
  • @BoboFeugo 你在想std::string::c_str(),返回值为const。对于非常量向量而言并非如此。

标签: c++ stdvector move-semantics


【解决方案1】:

你不能。

向量拥有它的缓冲区。你不能偷它。

您必须单独复制/移动元素,可选择使用帮您进行迭代的辅助算法 (std::copy/std::move)。

(另请注意,由于您的元素类型只是float,因此此处的移动副本。)

(另请注意,此算法std::move 与右值转换std::move 不同。)


考虑您是否真的需要这样做。您可以在需要时使用vec.data() 将向量的数据视为一个数组,只要您保持向量处于活动状态即可。这肯定比牺牲 RAII 更好?

【讨论】:

  • 那么你如何使用 std::move 来达到这个目的?
  • en.cppreference.com/w/cpp/algorithm/move 不过,因为你只有浮动,“移动”实际上只是一个副本。
  • 实际上我要求的move 不是标准算法中的那个,而是我想要move-semantics 之类的东西或浅拷贝。但正如大多数 cmet 所说的那样,这是不可能的,我可能不得不改变我的实现!
  • @Bobo 实际上,您是在问如何移动(或“窃取”)向量的内部缓冲区-您不能这样做。好吧,您可以将其窃取到另一个向量中,但这对您没有帮助;)我所说的std::move 是针对“个人”元素的。
  • @LightnessRacesinOrbit 为什么不反过来,从预先存在的分配中窃取向量?这个答案很失败
【解决方案2】:

这对我来说很方便将“类型化”向量内容窃取到“非类型化”向量中。

这就是我想做的:

std::vector<uint8_t>­one;
std::vector<V> other = std::move(one);

当我知道内容正是我所期望的(有一个运行时类型信息字段)时

我会用它来做一个无类型的“移动语义” 和一个类型化的类,其中部分底层表示 在向量中 - 仅在类型化的情况下,它是 Vs 的向量。

将其视为数据的不同“视图”。一般情况下数据 是无类型的,因为有特殊的边缘情况,但在通过处理它们之后 分支处理“正常”案例类型安全的方式会很方便..

我知道如果我抛出 std::vector 并执行此操作,我可以实现此行为 我使用直接指针算法的实现,然后我可以访问 在移动构造中,但我不想放弃向量......

只是想添加这个来说明背后可能存在什么样的理由 这类问题,我认为有时它是有效的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-21
    • 2014-04-18
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 2018-02-02
    相关资源
    最近更新 更多