将许多向量累积到一个容器中,无需复制
Accumulating many vectors into a single container w/o copying
在 C++11 中将许多std::vector
累积到一个std
容器中,每个都由给定的函数(我无法更改其 API)返回,而无需复制任何元素?
std::vector<int> make_vect();
container acc; // what is container?
do {
acc.append(std::move(make_vect())); // how to implement this?
} while(acc.size() < n);
注意 1,即使元素没有移动赋值运算符的移动构造函数,例如示例中的 int
,也不得复制这些元素。因此,您可以移动元素块(通过复制指针),但不能移动单个元素。
注意 2,container
必须允许使用单个迭代器迭代所有累积元素。所以std::vector<std::vector<>>
或类似的是不允许的。
显然,编写一些允许这样做的容器或使用std::list<std::vector<>>
并提供自己的迭代器是很简单的,但是std
库是否在没有此类用户编写的添加的情况下提供了所需的功能?
似乎请求的功能没有什么特别古怪的,我很惊讶即使使用 C++11 也很难(如果不是不可能的话)。
TL;DR 我不认为库存标准容器可以做到你的要求。原因如下。
请记住,容器的移动语义是有效的,因为它们是作为动态分配的内存的作用域绑定句柄实现的。移动容器实现为复制句柄,同时不接触包含的元素。
您的第一个(显式)约束是不复制任何容器的任何元素。这需要将句柄复制到您推定的acc_container
中。换句话说,你想要一个acc_container<std::vector<T>>
。任何标准容器都可以让您有效地做到这一点,无论单个元素T
有多大。
您的第二个(隐含的,从注释中推断)约束是您希望在所有单个向量的所有元素上具有统一的接口。换句话说,您想将其用作 acc_container<T>
.这需要在acc_container
的迭代器中增加额外的间接寻址,迭代器检测到它已到达当前vector<T>
之一的末尾,并跳转到下一个vector<T>
的开头。
标准库中不存在此类容器。
最简单的解决方法是使用std::vector<std::vector<T>>
(以避免复制T
元素),并编写自己的迭代器适配器(例如,使用 boost::indirect_iterator
,以提供对T
元素的迭代)。
不幸的是,即使您提供了从成员.begin()
/.end()
初始化这些间接迭代器的非成员begin()
/end()
函数,range-for 也不会使用 ADL 来查找这些函数,因为它会更喜欢旧成员函数.begin()
/.end()
。此外,您将无法例如 将T
元素直接insert()
到复合容器中,除非您还提供了非成员insert()
(以及其他类似功能)。
因此,如果你想要一个真正的复合容器,具有范围支持和成员函数的本机接口,你需要自己编写一个(std::vector<std::vector<T>
作为后端,整个std::vector<T>
接口写在它上面)。也许你可以在Boost邮件列表中推荐它作为一个不错的项目。
更新:这是Matt Austern关于分段迭代器和分层算法的旧论文的链接,该论文显示了这种方法的一些性能优势。缺点是你还需要让标准算法知道这些迭代器。
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 矢量如何将数据复制到另一个矢量?
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 链表,将列表复制到另一个列表
- 关于复制构造函数的一个棘手问题
- 将指向给定子类的指针从一个向量复制到另一个向量
- 有没有办法使用 strcpy 将字符串数组复制到另一个字符串或其他数组中?
- 为什么 std::map emplace 需要在 gcc 上有一个复制构造函数
- C++使用默认的复制构造函数,即使用户使用模板定义了一个复制构造函数
- Rcpp 需要一个复制构造函数
- 你能为具有常量成员的联合编写一个复制构造函数吗?
- 需要一个复制构造函数
- 如何从点赞列表中创建一个复制构造函数
- 返回值优化是否需要声明一个复制构造函数
- 给出两个二进制数,将一个子集从一个复制到另一个
- 是否应该为具有指向其父对象的指针的对象定义一个复制构造函数
- 为什么不是只有一个?复制构造函数和赋值操作符
- 为什么编译器需要一个复制构造函数,需要并移动一个并且不使用它们中的任何一个?
- 另一个复制算法
- 创建一个复制构造函数,该构造函数对输入对象进行深度复制(使用数组)