c++ - 嵌套可移动对象的 std::containers
问题描述
我有一个NoCopy
可移动但不可复制的课程。
我需要制作一个包含 3 个队列的向量NoCopy
。我可以创建一个空的,但没有办法添加任何元素。
我可以制作一个std::vector<NoCopy>
orstd::queue<NoCopy>
并填充它们。但不是为了std::vector<std::queue<NoCopy>>
。
MWE:
#include <iostream>
#include <vector>
#include <queue>
class NoCopy{
public:
NoCopy() = default;
NoCopy& operator = (const NoCopy&) = delete;
NoCopy(const NoCopy&) = delete;
NoCopy(NoCopy&&) = default;
NoCopy& operator = (NoCopy&&) = default;
};
using QNC = std::queue<NoCopy>;
int main(void) {
QNC q;
q.push(std::move(NoCopy()));
std::vector<NoCopy> ncvec;
ncvec.emplace_back();
std::cout << "Queue size " << q.size() << ", vector size: " << ncvec.size() << std::endl;
std::vector<QNC> qvec;
//????
return 0;
}
有任何想法吗?
解决方案
默认情况下,std::queue
基于std::deque
,不保证是nothrow-movable。其他合适的标准容器也不是std::list
;这些规则允许始终分配至少一个节点/块的实现。 std::vector
移动时使用副本重新分配可能会抛出(以保证异常安全),除非该类型根本不可复制,并且这两个容器也不会从其元素类型传播不可复制性,但如果您尝试则会失败。最后一个可以说是标准中的一个缺陷,因为对这种传播的期望不断提高,但修复它与对不完整类型的支持不兼容:
struct Node {
std::vector<Node> children;
// …
};
请注意,libstdc++ 和 libc++都使这两个容器不可移动(在每种情况下都是从版本 9 开始),这是允许的扩展,但 MSVC 的 STL 不允许。
您仍然可以使用std::vector<QNC> v(3);
; 构造函数“知道”永远不需要重新分配。或者您可以提供一个不可复制或不可移动的包装器(例如,派生自 的类);std::queue
前者将放弃 的异常安全性std::vector
,而后者将std::terminate
在移动底层容器确实抛出时调用。
推荐阅读
- python - 如何对列表列表重复一系列过程和计算?
- matlab - 如何正确应用 ODE45 求解器
- python-3.x - 如何将 tensorflow.python.framework.ops.EagerTensor 保存为文本?
- android - 如何将数据从 ArrayList 显示到 RecycleView?
- javascript - 从 HTML 字符串替换样式标记内的双引号以在 DOM 中正确呈现
- mysql - 使用 PDO 执行“SHOW PROCESSLIST”不会返回进程列表
- docker - Kong:缺少用于连接的数据库
- php - EA 插件给出 请确保这不是一个被遗忘的调试语句
- c++ - 在 SPOJ 上提交代码会导致运行时错误 (SIGABRT)
- angularjs - 为什么我在 Angular 中遇到错误。无法获取 /