Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将多个向量累积到单个容器中,而不进行复制_C++_C++11_Containers_Move - Fatal编程技术网

C++ 将多个向量累积到单个容器中,而不进行复制

C++ 将多个向量累积到单个容器中,而不进行复制,c++,c++11,containers,move,C++,C++11,Containers,Move,在C++11中,是否可以将给定函数(其API我无法更改)返回的许多std::vectors累积到std容器中,而不复制任何元素 std::vector<int> make_vect(); container acc; // what is container? do { acc.append(std::move(make_vect())); // how to implement this? } while(acc.siz

在C++11中,是否可以将给定函数(其API我无法更改)返回的许多
std::vector
s累积到
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);
std::vector make_vect();
集装箱acc;//什么是集装箱?
做{
acc.append(std::move(make_vect());//如何实现?
}而(根据尺寸()
注意1即使元素没有move赋值运算符的move构造函数,也不能复制元素,例如示例中的
int
。因此,您可以移动一块元素(通过复制指针),但不能移动单个元素

注意2容器必须允许使用单个迭代器对所有累积元素进行迭代。因此,不允许使用
std::vector
或类似工具

显然,编写一些容器来允许这一点或使用
std::list
并提供您自己的迭代器是很简单的,但是
std
库是否提供了所需的功能,而无需用户编写的添加


似乎请求的功能并没有什么特别奇怪的地方,我很惊讶,即使使用C++11,它也有多么困难(如果不是不可能的话);DR我认为库存标准容器无法满足您的要求。原因如下

请记住,容器的移动语义是有效的,因为它们被实现为动态分配内存的范围绑定句柄。移动容器实现为复制句柄,而不接触包含的元素

第一个(显式)约束是不复制任何容器的任何元素。这就需要将句柄复制到假定的
acc\u容器中。换句话说,您需要一个
acc\u容器
。无论单个
T
元素有多大,任何标准容器都可以让您高效地执行此操作

第二个(隐式的,从注释推断的)约束是,您希望在所有单个向量的所有元素上都有一个统一的接口。换句话说,您希望将其用作
acc\u容器
。这需要在
acc_容器
的迭代器中进行额外的间接寻址,迭代器检测到它已到达当前
向量
之一的末尾,并跳到下一个
向量
的开头

标准库中不存在这样的容器

最简单的解决方法是使用
std::vector
(避免复制
T
元素),并编写自己的迭代器适配器(例如,使用
boost::indirect_迭代器
,在
T
元素上提供迭代)

不幸的是,即使您提供了从成员
.begin()
/
.end()
初始化这些间接迭代器的函数,range for也不会使用ADL来查找这些函数,因为它将首选旧成员函数
.begin()
/
.end()
。此外,您将无法将
insert()
T
元素直接插入复合容器,除非您还提供非成员
insert()
(以及类似的其他功能)


因此,如果您想要一个真正的复合容器,具有支持范围和成员函数的本机接口,您需要自己编写一个容器(使用
std::vector函数的返回值已经是右值(如果它不是左值引用),所以您不需要
std::move
它。“不复制任何元素”允许移动元素吗?@DyP是的。我只想强调,在该阶段不进行复制,并且
acc.append()
(不管是什么)应该使用右值引用。这是对您的问题的直接回答,但可能不是您想要的:
std::anycontainer
,您可以在其中移动向量。这不适合以后访问。@stefaanv是的,我知道该解决方案。这正是我想要避免的。您想要
acc_container
为什么?为什么
std::deque
(内部具有前一种结构)?@Walter-
std::deque
在要执行的内部“块”的长度和数量上维护精心选择的不变量-不仅仅是任何旧向量都可以。@Walter First:a
std::deque
不公开这些内部“页面”此外,实际上,
std::deque
有固定大小的页面,而不是像附加任意向量时需要的可变大小的页面。最后,对于内部页面,如何在不复制的情况下进行附加?记住,移动容器就是复制句柄。@Walter我用一个链接更新了我的答案,链接到一个g关于这个主题的论文。@TemplateRex thnx。是的,它看起来真的很旧(虽然我找不到日期,但他们没有引用比1998年更近的东西)。他们甚至在致谢中感谢我们自己的Dietmar Kuehl。。。