为什么编译器不会自动推断出变量即将超出范围,因此将其视为右值引用?
以这段代码为例:
#include <string>
int foo(std::string && bob);
int foo(const std::string & bob);
int main()
{
std::string bob(" ");
return foo(bob);
}
检查汇编代码清楚地表明,const & 版本的“foo”在函数末尾被调用。
此处的编译器资源管理器链接:https://godbolt.org/g/mVi9y6
编辑:澄清一下,我不是在寻找有关移动变量的替代方法的建议。我也不想理解为什么编译器选择 foo 的 const& 版本。这些是我理解得很好的事情。
我有兴趣了解一个反例,其中编译器在变量超出范围之前将其最后一次使用转换为右值引用会在生成的代码中引入严重的错误。如果编译器实现这种“优化”,我想不出代码会中断。
如果当编译器自动将最后一次使用即将超出范围的变量作为右值引用时没有中断代码,那么为什么编译器不将其实现为优化?
我的假设是一些代码会破坏编译器实现“优化”的地方,我想知道这些代码是什么样的。
我上面详述的代码是一个代码示例,我相信它会从这样的优化中受益。
函数参数的计算顺序,例如 operator+(foo(bob), foo(bob)) 是实现定义的。因此,代码如
return foo(bob) + foo(std::move(bob));
是危险的,因为您使用的编译器可能会首先评估 + 运算符的右侧。这将导致字符串 bob 可能被移动,并使其处于有效但不确定的状态。随后,将使用生成的修改后的字符串调用 foo(bob)。
在另一个实现中,可能首先评估非移动版本,并且代码将按照非专家所期望的方式运行。
如果我们假设某些 future 版本的 c++ 标准实现了允许编译器将变量的最后一次使用视为右值引用的优化,那么
return foo(bob) + foo(bob);
毫无意外地工作(假设 foo 的适当实现,无论如何)。
这样的编译器,无论它对函数参数使用什么求值顺序,总是会在这种情况下将 bob 的第二次(也是最后一次)用法作为右值引用来求值,无论它是左侧,还是运算符 + 的右侧。
最佳答案
这是一段完全有效的现有代码,但您的更改会破坏该代码:
// launch a thread that does the calculation, moving v to the thread, and
// returns a future for the result
std::future<Foo> run_some_async_calculation_on_vector(std::pmr::vector<int> v);
std::future<Foo> run_some_async_calculation() {
char buffer[2000];
std::pmr::monotonic_buffer_resource rsrc(buffer, 2000);
std::pmr::vector<int> vec(&rsrc);
// fill vec
return run_some_async_calculation_on_vector(vec);
}
构造容器的移动总是传播其分配器,但复制构造容器则不必,polymorphic_allocator 是一个分配器,不会在容器复制构造上传播.相反,它总是恢复到默认内存资源。
这段代码在复制时是安全的,因为 run_some_async_calculation_on_vector 接收到从默认内存资源分配的拷贝(希望它在整个线程的生命周期中持续存在),但是被一个移动完全破坏了,因为那样的话它会保留 rsrc 作为内存资源,一旦 run_some_async_calculation 返回,它将消失。
关于c++ - 编译器推导超出范围的变量的右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45763943/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.
如何将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.你能做的最好的事情是:
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路