c – push_back vs emplace_back到std :: vector
在
here和
here中存在类似的问题,但我认为我没有得到明确的答案然后我重新提出了问题.
C 11标准有两种方法可以在向量的末尾添加一个新元素,它们是std :: vector :: push_back和std :: vector :: emplace_back. 它们之间的区别是std :: vector :: emplace_back构造对象到位,std :: vector :: push_back基本上复制对象(或基本类型)或将其移动到向量的末尾. 然后std :: vector :: push_back看起来更好的选择将原始类型添??加到std :: vector中.例如: std::vector<int> vVec; vVec.push_back(10); int iVar 30; vVec.push_back(iVar); 但是当我们谈论对象时,我并不是那么清楚.我们以std :: string的向量为例.如果我想添加一个文字字符串,我将使用std :: vector :: emplace_back,当我想复制或移动一个字符串对象时,我将使用std :: vector :: push_back? 为了更清楚我要问的内容,让我们看几个场景: 第一种情况: std::vector<string> vVec; std::string sTest(“1st scenario”); vVec.push_back(sTest); vVec.emplace_back(sTest); Push_back复制sTest并关联到vVec末尾的新元素,同时emplace_back在vVec的末尾创建字符串对象并将sTest的内容复制到其中. 第二种情况: std::vector<string> vVec; std::string sTest1(“2st scenario”); std::string sTest2(“2st scenario”); vVec.push_back(move(sTest1)); vVec.emplace_back(move(sTest2)); Push_back已准备好移动语义,但emplace_back会发生什么?在这种情况下哪一个更有效? 第三种情况: std::vector<string> vVec; std::string sTest("3st scenario"); vVec.push_back(sTest.substr(4,4)); vVec.emplace_back(sTest.substr(4,4)); 因为std :: string :: substr返回另一个std :: string,我们和第二个场景有相同的情况? 结论 如果std :: vector :: emplace_back仅在涉及文字时(就地构造)比std :: vector :: push_back更有效,它是否真的合理使用?如果有的话,你能给我一些例子吗? 重要的是要注意到std :: vector :: emplace_back是在c 11中实现的而不是在c 0x中然后我认为它有充分的理由存在. 解决方法
它在您的三个场景中没有太大的区别,因为两个函数将在场景1中调用一个复制构造函数,在场景2或3中调用一个移动构造函数.
但是,如果你想构造一个10’x’字符串呢?在这种情况下,您的选择是 vVec.push_back(std::string(10,'x')); vVec.emplace_back(10,'x'); 在这种情况下,push_back涉及调用自定义字符串构造函数然后调用移动构造函数,但emplace_back直接调用自定义字符串构造函数,保存对移动构造函数的调用. std :: string的移动构造函数可能不是很大,但是当对象没有有效的移动构造函数时,emplace函数可以保存,并且即使类类型由于某种原因具有删除的移动构造函数也可以使用. (好吧,如果删除移动和复制构造函数,std :: vector将不会高兴,但其他容器也可以.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |