我的数据结构通常通过 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
};
但我不喜欢通过 vector 中的智能指针这种额外的间接寻址,我认为它没有表达我想要的语义。
我认为 vector 应该拥有表达式,而不是智能指针拥有表达式。
但我有一个问题,表达式总是在智能指针(或至少作为原始指针)中创建:
std::unique_ptr<Expr> parse_expr() { ... }
有没有一种优雅的方式可以从 parse_expr 转移所有权?调用(类型为 std::unique_ptr<Expr> 到 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());
Exprmust not be copied while doing so.
然后移动,假设没问题:
exprs.push_back(std::move(*parse_expr()));
但是,首先要考虑为什么它们的表达式是动态分配的。据推测,它们是指向多态基础子对象的指针。在这种情况下,从基移出可能对您没有用,基对象数组的整个概念可能是错误的。
Exprcan be a base class
在这种情况下 std::vector<std::unique_ptr<Expr>>正是您所需要的。
关于c++ - 将智能指针所有权转移到容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54887391/
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/
是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述
我们如何捕获或/和处理ruby中所有未处理的异常?例如,这样做的动机可能是将某种异常记录到不同的文件或发送电子邮件给系统管理。在Java中我们会做Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandlerex);在Node.js中process.on('uncaughtException',function(error){/*code*/});在PHP中register_shutdown_function('errorHandler');functionerrorHandler(){$error=error_