部分std ::移动一个向量?或者如何在没有新内存分配的情况下进行拆分?

时间:2017-03-26 20:32:43

标签: c++11 move move-semantics

当我们移动std::vector时,我们只会窃取其内容。所以这段代码:

std::vector<MyClass> v{ std::move(tmpVec) };

不会分配新内存,也不会调用MyClass的任何构造函数。

但是,如果我想分割临时矢量怎么办?从理论上讲,我可以像之前那样窃取内容并将其分发到新的向量中。在实践中我不能这样做。我发现迄今为止最好的解决方案是使用<algorithm>标头中的std::move()。但是这里将为每个新向量调用operator new。此外,将为我们移动的每个元素调用移动构造函数(如果可用)。

我还能做什么(c ++ 17计数)?

2 个答案:

答案 0 :(得分:1)

  

理论上,我可以像之前那样窃取内容并将其分发到新的载体中。

不,你不能。

内存分配不能分解为多个内存分配。至少,不是没有进行多次内存分配,而是将元素从原始内容复制/移动到那些单独的部分中。

如果没有实际将元素复制/移动到那些不同的内存缓冲区,则无法创建具有不同存储的单独vector。您当然可以使用vector的单独范围,并使用此类范围(迭代器/指针对,gsl::span等)执行任何操作。但是每个范围总是引用源vector最终拥有的元素;他们不能独立拥有vector的子范围。

答案 1 :(得分:1)

您可以编写一个存储两个指针的span类,并且不拥有它们之间的数据。它可以有很多类似矢量的操作。

它还应支持将自身(无分配)切片为子组件。

您可以编写一个具有这两个指针的shared_span类,以及一个表示(可能共享)底层缓冲区所有权的shared_ptr。它应支持span的操作,但返回span的函数(如without_front(std::size_t count=1))应返回shared_span(具有共享所有权)。

您可以轻松地从vectorshared_span编写移动构造函数。您甚至可以使用一个特殊的分配器从shared_spanvector编写一个函数,该函数在它增长之前不会分配。完全可移植将是非常困难的。

如果有可能(我不确定),您可以选择std::vector,将其存储空间移至shared_ptr<std::vector>,将其提供给分配器,构建两个使用std::vector<T, special_allocator>的存储空间记忆,做你想做的事。

但您可以使用vector代码替换shared_span执行此操作的请求。 shared_span甚至可以有一个额外的&#34;死&#34;在它使用的缓冲区之前/之后的内存,使其性能接近std::vector

您可以使用的gsl库中有一个范围。我不知道公开的shared_span