我最近读到std::move如何通过移动值而不是复制它们来加速代码。所以我做了一个测试程序来比较使用std::vector的速度。代码:#include#include#include#ifdefWIN32#include#else#include#include#endif#undefmax//ReturnstheamountofmillisecondselapsedsincetheUNIXepoch.Worksonboth//windowsandlinux.uint64_tGetTimeMs64(){#ifdef_WIN32//WindowsFILETIMEft;LARGE_INT
它们是否跨不同的目标文件工作?它们跨不同的DLL工作吗?我知道这取决于编译器。我很好奇是否有任何编译器和优化设置可以使这项工作正常进行。 最佳答案 通常,是的,但原则上,使用链接时间优化(-flto用于GCC/Clang编译器和链接器)或链接时间代码生成(/LTCG和/GL用于MSVC的编译器和链接器),编译器和链接器可以利用它们共享的知识,也许还可以利用内联代码和省略拷贝。GCC的manual状态:[...]thiscausesalltheinterproceduralanalysesandoptimizationsinGCCto
编译器如何确定何时对RVO是安全的?不,我不是说右值,而是左值——如果我理解正确的话,RVO的工作原理是将目标地址“转发”给方法,因此它返回到目标地址而不是临时地址,然后复制/分配给目标。但是编译器如何知道执行RVO是安全的呢?如果左值中已经有一些数据,包括动态分配的资源怎么办?这种情况下的RVO可能会导致资源泄漏。也许有一些规则指定是否适用于执行优化或坚持使用复制或赋值? 最佳答案 RVO只能初始化一个新的对象,不能重新分配一个已经存在的对象。所以在这种情况下:Thingthing=make_thing();thing的地址被传递
查看下面的代码示例,我希望它作为返回值优化(RVO)的一部分执行强制复制省略,并使用C++17(/std:c++17)进行编译,但它在Visual上编译时出现错误Studio2017(我使用的是VS17,更具体地说是15.9.8)。classNoCopyOrMove{public:NoCopyOrMove()=default;NoCopyOrMove(inta,intb){}NoCopyOrMove(constNoCopyOrMove&)=delete;NoCopyOrMove&operator=(constNoCopyOrMove&)=delete;NoCopyOrMove(NoCo
如果我没看错的话,move语义允许从临时的、未命名的对象中move和重用资源。RVO,尽管之前的move语义更进一步,并“窃取”了整个对象以避免额外的构造函数调用和赋值/复制函数。这对我来说似乎有点违反直觉,如果被调用的构造函数直接使用最终左值目标的地址直接将数据放置在用户需要的位置,不是会更快、更简单且用户显而易见吗?我的意思是,“在这个位置创建这个对象”似乎比“在某个地方创建这个对象,然后将它复制到正确的位置”更直观一些。 最佳答案 是的,它“有点违反直觉”。启用复制省略后,构造函数的所有副作用也将被省略。#includestr
众所周知,std::move不应应用于函数返回值,因为它可以防止RVO(返回值优化)。我感兴趣的问题是,如果我们肯定知道RVO不会发生,我们应该怎么做。C++14标准是这么说的[12.8/32]Whenthecriteriaforelisionofacopy/moveoperationaremet,butnotforanexception-declaration,andtheobjecttobecopiedisdesignatedbyanlvalue,orwhentheexpressioninareturnstatementisa(possiblyparenthesized)id-ex
假设我们有这种情况std::stringv_1(){return"name";}std::stringtest=v_1();这里应用的是RVO吗?我认为答案是否定的,因为应用RVO的规则之一是:“如果一个函数按值返回一个类类型,并且return语句的表达式是一个具有自动存储持续时间的非volatile对象的名称,这不是函数参数,也不是catch子句参数,并且与函数的返回类型具有相同的类型(忽略顶级cv限定),然后省略复制/移动”在这种情况下,返回的对象与函数的返回类型不具有相同的类型,但我不是100%在这里不应用RVO。非常感谢。附言。关于这个话题https://www.youtube
一个函数需要返回两个值给调用者。什么是最好的实现方式?选项1:pairmyfunc(){...returnmake_pair(getU(),getV());}pairmypair=myfunc();选项1.1://SamedefnUu;Vv;tie(u,v)=myfunc();选项2:voidmyfunc(U&u,V&v){u=getU();v=getV();}Uu;Vv;myfunc(u,v);我知道选项2没有复制/移动,但它看起来很丑。Option1,1.1中会发生任何复制/移动吗?假设U和V是支持复制/移动操作的大型对象。问:理论上任何RVO/NRVO优化都可以按照标准进行吗?如
我可能问了一个愚蠢的问题,但我查看了RVO的维基百科页面here并且不停地想知道这种行为是否错误。我在我的机器上试过了,尽管优化级别,RVO还是完全启动了。如果构造函数中确实发生了一些大的事情怎么办?我知道不应该,但万一呢?我不明白为什么在构造函数中有副作用时仍然会发生RVO。编辑:-fno-elide-constructors似乎停止了RVO。但问题仍然存在。EDIT2:更严肃地说,有多少人知道这样的事情?它可能在标准中,但在我看来它仍然是一个非常丑陋的功能。至少编译器应该默认禁用它,并为了解这一点的人提供一个开关。:)编辑3:我仍然坚持认为这真的很糟糕。:).我不认为我知道有任何其
在过去一天左右的时间里,我一直在学习移动构造函数,试图坚持大多数人似乎建议的按值(value)返回的一般规则,并且遇到了一个有趣的(对我而言)困境。假设我有一个昂贵的构造/复制类“C”,它具有正确定义的复制构造函数、赋值运算符、移动构造函数和移动赋值运算符。首先,这段代码如我所料省略了复制构造函数:Cmake_c1(){returnC();}这样做:Cmake_c2(){Ctmp;returntmp;}这也是(无论我传递1还是2):Cmake_c3(inta){returna==1?make_c1():make_c2();}当我谈到这里时,我遇到了一个问题:Cmake_c4(inta)