最近我从 cppreference.../vector/emplace_back 中阅读了一个示例:
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
我的问题:这 std::move 真的需要吗?我的观点是这个 p_name 没有用在构造函数的主体中,所以,也许语言中有一些规则默认使用 move 语义?
将初始化列表中的 std::move 添加到每个重成员(如 std::string、std::vector)会非常烦人。想象一下数百个用 C++03 编写的 KLOC 项目——我们是否应该在任何地方添加这个 std::move?
这个问题:move-constructor-and-initialization-list答案是:
As a golden rule, whenever you take something by rvalue reference, you need to use it inside std::move, and whenever you take something by universal reference (i.e. deduced templated type with &&), you need to use it inside std::forward
但我不确定:按值传递而不是通用引用?
[更新]
为了让我的问题更清楚。可以将构造函数参数视为 XValue - 我的意思是过期值吗?
在这个例子中我们不使用 std::move:
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor probably correct
}
那么,这里是否需要:
void President::setDefaultName()
{
std::string local = "SO";
name = local; // std::move OR not std::move?
}
对我来说,这个局部变量是过期变量 - 所以可以应用 move 语义......这类似于按值传递的参数......
最佳答案
My question: is this std::move really needed? My point is that compiler sees that this p_name is not used in the body of constructor, so, maybe, there is some rule to use move semantics for it by default?
一般来说,当你想把一个左值变成一个右值,那么是的,你需要一个std::move()。另见 Do C++11 compilers turn local variables into rvalues when they can during code optimization?
void President::setDefaultName()
{
std::string local = "SO";
name = local; // std::move OR not std::move?
}
For me this local variable is expiring variable - so move semantics could be applied... And this similar to arguments passed by value....
在这里,我希望优化器消除多余的 local ALTOGETHER;不幸的是,实际情况并非如此。当堆内存开始发挥作用时,编译器优化会变得很棘手,请参阅 BoostCon 2013 Keynote: Chandler Carruth: Optimizing the Emergent Structures of C++ .我从 Chandler 的演讲中得出的一个结论是,当涉及到堆分配的内存时,优化器往往会放弃。
请参阅下面的代码,了解一个令人失望的示例。在这个例子中我没有使用 std::string 因为这是一个高度优化的类,带有内联汇编代码,通常会产生违反直觉的生成代码。为了增加侮辱, std::string 粗略地说至少是 gcc 4.7.2 中的引用计数共享指针( copy-on-write optimization ,现在被 std::的 2011 标准禁止字符串)。所以没有std::string的示例代码:
#include <algorithm>
#include <cstdio>
int main() {
char literal[] = { "string literal" };
int len = sizeof literal;
char* buffer = new char[len];
std::copy(literal, literal+len, buffer);
std::printf("%s\n", buffer);
delete[] buffer;
}
显然,根据“as-if”规则,生成的代码可以优化为:
int main() {
std::printf("string literal\n");
}
我已经在启用链接时间优化 (LTO) 的 GCC 4.9.0 和 Clang 3.5 上进行了尝试,但没有一个可以将代码优化到这个级别。我查看了生成的汇编代码:它们都在堆上分配了内存并进行了复制。嗯,是的,这令人失望。
堆栈分配的内存不同:
#include <algorithm>
#include <cstdio>
int main() {
char literal[] = { "string literal" };
const int len = sizeof literal;
char buffer[len];
std::copy(literal, literal+len, buffer);
std::printf("%s\n", buffer);
}
我已经检查了汇编代码:在这里,编译器能够将代码基本上简化为 std::printf("string literal\n"); .
因此,我对示例代码中多余的 local 可以被消除的期望并非完全不受支持:正如我后面的堆栈分配数组示例所示,可以做到。
Imagine hundreds of KLOC project written in C++03 - shall we add everywhere this
std::move?
[...]
But I am not sure: passing by value is rather not universal reference?
"Want speed? Measure." (作者 Howard Hinnant)
您很容易发现自己进行优化只是为了发现您的优化使代码变慢。 :( 我的建议与 Howard Hinnant 的建议相同:衡量。
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor probably correct
}
是的,但是我们有针对这种特殊情况的规则:它被称为命名返回值优化 (NRVO)。
关于c++ - 对于按值传递的重成员,构造函数的初始化列表中真的需要 std::move 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23929800/
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc