C++11 移动一个向量?或者如何在没有新内存分配的情况下进行拆分?
当我们移动std::vector时,我们只是窃取了它的内容。所以这个代码:C++11 移动一个向量?或者如何在没有新内存分配的情况下进行拆分?,c++11,move,move-semantics,C++11,Move,Move Semantics,当我们移动std::vector时,我们只是窃取了它的内容。所以这个代码: std::vector<MyClass> v{ std::move(tmpVec) }; std::vector v{std::move(tmpVec)}; 不会分配新内存,不会调用MyClass的任何构造函数 但是如果我想分割一个临时向量呢?理论上,我可以像以前一样窃取内容并将其分发到新的载体中。实际上我不能这样做。到目前为止,我找到的最佳解决方案是使用from标题。但是在这里,将为每个新向量调用操作符
std::vector<MyClass> v{ std::move(tmpVec) };
std::vector v{std::move(tmpVec)};
不会分配新内存,不会调用MyClass
的任何构造函数
但是如果我想分割一个临时向量呢?理论上,我可以像以前一样窃取内容并将其分发到新的载体中。实际上我不能这样做。到目前为止,我找到的最佳解决方案是使用from
标题。但是在这里,将为每个新向量调用操作符new
。此外,移动构造函数(如果可用)将为我们移动的每个元素调用
我还能做什么(c++17计数)
理论上,我可以像以前一样窃取内容并将其分发到新的载体中
不,你不能
内存分配不能拆分为多个内存分配。至少,必须进行多次内存分配,然后将元素从原始元素复制/移动到这些单独的片段中 如果不将元素实际复制/移动到这些不同的内存缓冲区,则无法创建具有不同存储的单独的
向量。当然,您可以对该向量取不同的范围,并对这些范围(迭代器/指针对,gsl::span
等)执行任何可以执行的操作。但每个范围总是引用源向量最终拥有的元素;它们不能独立拥有向量的子范围
理论上,我可以像以前一样窃取内容并将其分发到新的载体中
不,你不能
内存分配不能拆分为多个内存分配。至少,必须进行多次内存分配,然后将元素从原始元素复制/移动到这些单独的片段中
如果不将元素实际复制/移动到这些不同的内存缓冲区,则无法创建具有不同存储的单独的向量。当然,您可以对该向量取不同的范围,并对这些范围(迭代器/指针对,gsl::span
等)执行任何可以执行的操作。但每个范围总是引用源向量最终拥有的元素;它们不能独立地拥有向量的子范围
您可以编写一个span
类来存储两个指针,而不拥有它们之间的数据。它可以有许多类似向量的操作
它还应该支持将自身切片(无需分配)到子组件中
您可以编写一个既有这两个指针的shared_span
类,也可以编写一个shared_ptr
类,它表示(可能是共享的)底层缓冲区的所有权。它应该支持span
的操作,除了返回span
的函数(比如没有前端(std::size\u t count=1)
)应该返回共享的span
(具有共享所有权)
您可以轻松地将移动构造函数从vector
写入shared\u span
。您甚至可以使用一个特殊的分配器将函数从shared\u span
写入vector
,该分配器在函数增长之前不会进行分配。使其完全可移植将是非常困难的
如果可能(我不确定),您可以获取一个std::vector
,将其存储移动到一个共享的\u ptr
,将其提供给分配器,构建两个使用该内存的std::vector
,然后执行您想要的操作
但您可以将执行此操作的vector
请求替换为使用共享span
的代码shared\u span
甚至可以在使用缓冲区之前/之后有一个额外的“死”内存概念,使其性能接近std::vector
在gsl
库中有一个跨度,您可以使用它。我不知道有一个公共可用的shared\u span
您可以编写一个span
类来存储两个指针,并且不拥有它们之间的数据。它可以有许多类似向量的操作
它还应该支持将自身切片(无需分配)到子组件中
您可以编写一个既有这两个指针的shared_span
类,也可以编写一个shared_ptr
类,它表示(可能是共享的)底层缓冲区的所有权。它应该支持span
的操作,除了返回span
的函数(比如没有前端(std::size\u t count=1)
)应该返回共享的span
(具有共享所有权)
您可以轻松地将移动构造函数从vector
写入shared\u span
。您甚至可以使用一个特殊的分配器将函数从shared\u span
写入vector
,该分配器在函数增长之前不会进行分配。使其完全可移植将是非常困难的
如果可能(我不确定),您可以获取一个std::vector
,将其存储移动到一个共享的\u ptr
,将其提供给分配器,构建两个使用该内存的std::vector
,然后执行您想要的操作
但您可以将执行此操作的vector
请求替换为使用共享span
的代码shared\u span
甚至可以在使用缓冲区之前/之后有一个额外的“死”内存概念,使其性能接近std::vector
在gsl
库中有一个跨度,您可以使用它。从理论上讲,我不知道一个公共可用的共享\u span
,我的意思是:向量基本上是指向内存开始和结束的两个指针。因此,理论上,我们可以将任何指针指定为从这个范围到新向量的开始/结束,而无需分配。