加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – push_back vs emplace_back到std :: vector

发布时间:2020-12-16 10:37:23 所属栏目:百科 来源:网络整理
导读:在 here和 here中存在类似的问题,但我认为我没有得到明确的答案然后我重新提出了问题. C 11标准有两种方法可以在向量的末尾添加一个新元素,它们是std :: vector :: push_back和std :: vector :: emplace_back. 它们之间的区别是std :: vector :: emplace_bac
在 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将不会高兴,但其他容器也可以.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读