草庐IT

c++ - 将右值作为非常量引用传递(VS 警告 C4239)

coder 2024-02-14 原文

我想做的(使用 C++ lambda)是有效的:

std::vector<MyType> GetTheArray () {return something;}

const auto DoSomething = [](std::vector<MyType> & array)
{
     //Some processing that involves either sorting the 'array' or setting temporary flags on the items
};

DoSomething (GetTheArray ());

这在标准 C++ 中似乎是不允许的,因为右值不能作为非常量引用传递。

我的问题:

1) 有没有办法使用类型转换来做到这一点,或者我是否必须创建一个临时变量来存储 GetTheArray () 的结果?

2) 在 C++ 中不允许这样做是否有充分的理由?

请注意,从“GetTheArray”返回的“某物”是一个动态构建的数组,而不是存储值。

最佳答案

从评论看来,你想要的是获取一个 vector ,对其进行破坏性修改(在无法重置原始状态的意义上),然后在内部使用结果。并且您希望它对左值和右值都有效。

下一个问题是在左值的情况下,保存原始容器的代码在函数调用完成后是否需要它,以及它是否需要 vector 的原始状态。根据您的答案,您有不同的解决方案:

持有左值的调用者在调用后不再使用它

(或者,持有左值的调用者需要原始状态)

这是最简单的情况。然后你的函数应该按值获取容器。如果调用者有一个左值,它可以std::move 来避免复制(它不再关心该对象)或复制,这可能更昂贵但留下原始容器保持不变。

如果使用右值 调用该函数,则拷贝将被删除或转换为廉价的隐式移动。

持有左值的调用者不需要原始状态,但需要容器

这种情况比较困难,您需要为同一个函数(或 lambda)提供两个重载,一个采用此调用者使用的 lvalue ,另一个采用 < em="">rvalue-reference 用于调用者递交临时值的情况。在这两种情况下,绑定(bind)都是便宜的。虽然这需要更多代码,但您可以根据另一个实现一个重载:

rtype f(std::vector<Data> & );   // for lvalues
rtype f(std::vector<Data> && v)  // for rvalues
   { return f(v); }              // v is an lvalue here

您正在执行 lambda 的事实可能会使这稍微复杂一些,但希望不会太复杂。

关于c++ - 将右值作为非常量引用传递(VS 警告 C4239),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16216043/

有关c++ - 将右值作为非常量引用传递(VS 警告 C4239)的更多相关文章

  1. ruby-on-rails - Railstutorial : db:populate vs. 工厂女孩 - 2

    在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  5. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  6. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  7. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  8. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将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.你能做的最好的事情是:

  10. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

随机推荐