在C ++ 11中是否可以累积许多std::vector
,每个{1}返回给定一个函数(我的API无法更改)到std
容器而不复制任何元素?
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也有多难(如果不是不可能的话)。
答案 0 :(得分:3)
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
,以提供{{1}的迭代1}}元素)。
不幸的是,即使您提供non-member begin()
/ end()
函数来初始化成员T
/ .begin()
中的这些间接迭代器,range-for也不会使用ADL来查找这些函数,因为它会优先选择旧成员函数.end()
/ .begin()
。此外,您将无法例如.end()
insert()
元素直接放入您的复合容器中,除非您还提供非成员T
(并且类似于其他功能)。
因此,如果你想要一个真正的复合容器,具有范围支持和成员函数的本地接口,你需要自己编写一个(insert()
作为后端,以及整个{{1在它上面写的接口)。也许你可以在Boost邮件列表上建议它作为一个很好的项目。
更新:这是Matt Austern在Segmented Iterators and Hierarchial Algorithms上发表的一篇旧论文的链接,该论文显示了这种方法带来的一些性能优势。缺点是你还需要让标准算法知道这些迭代器。