c++ - 将智能指针所有权转移到容器
问题描述
我有通常通过 管理的数据结构,std::unique_ptr
例如 AST 中的表达式。
struct BinExpr {
std::unique_ptr<Expr> left; // Left owns the expression
std::unique_ptr<Expr> right; // Right owns the expression
};
在大多数情况下效果很好。
但有时我没有固定数量的表达式来拥有,例如在列表中
struct ListExpr {
std::vector<std::unique_ptr<Expr>> exprs; // Exprs owns pointers which each own an expression
};
但我不喜欢通过向量中的智能指针进行的这种额外间接,我认为它没有表达我想要的语义。
我认为向量应该拥有表达式,而不是拥有表达式的智能指针。
但我有一个问题,表达式总是在智能指针(或至少作为原始指针)中创建:
std::unique_ptr<Expr> parse_expr() { ... }
有没有一种优雅的方法可以将所有权从parse_expr
调用(类型std::unique_ptr<Expr>
为 a )转移std::vector<Expr>
?当然Expr
,这样做时不能复制。像
std::vector<Expr> exprs;
exprs.push_back(move_from_ptr_to_vec(parse_expr()));
所以基本上,目前我像这样使用它们
std::vector<std::unique_ptr<Expr>> exprs;
exprs.push_back(std::move(parse_expr()));
return std::unique_ptr<ListExpr>(exprs); // List has a std::vector<std::unique_ptr<Expr>>
但我想要那样
std::vector<Expr> exprs;
exprs.push_back(parse_expr());
return std::unique_ptr<ListExpr>(exprs); // List has a std::vector<Expr>
解决方案
std::vector<Expr> exprs; exprs.push_back(parse_expr());
不起作用,因为parse_expr()
返回一个智能指针。您必须通过指针间接获取指向的对象:
exprs.push_back(*parse_expr());
Expr
这样做时不得复制。
然后移动,假设没问题:
exprs.push_back(std::move(*parse_expr()));
但是,首先考虑一下为什么它们的表达式是动态分配的。据推测,它们是指向多态基础子对象的指针。在这种情况下,从基础移动可能对您没有用,基础对象数组的整个概念可能是错误的。
Expr
可以是基类
在这种情况下std::vector<std::unique_ptr<Expr>>
,这就是您所需要的。
推荐阅读
- loops - 试图找到一种使用 johnny-five.io 以不同速度控制伺服系统的好方法
- javascript - 仅在已加载图像后执行图像分析
- c# - RestSharp - 如何在不上传文件的情况下发送多部分/表单数据正文请求?
- java - 产品 ini 文件名未设置为启动器名称
- google-apps-script - 在哪里可以找到(跟踪)Google Apps Script API 更改和新功能?
- azure-active-directory - 在查询 https://graph.microsoft.com/beta/users/delta?$select= 时检测已删除的用户
- sql-server - 将新数据从一个表复制到另一个表
- jenkins - Jenkins Git-Push 只有主分支
- sql - 通过动态参数按时间分组
- android - ViewPager 和 YouTube API