jjzjj

c++ - push_back 与 emplace_back 到 std::vector<std::string>

coder 2024-02-06 原文

类似的问题存在于herehere但我认为我们还没有得到明确的答案然后我重新提出问题。

C++11 标准有两种在 vector 末尾添加新元素的方法,它们是 std::vector::push_backstd::vector::emplace_back.

它们之间的区别在于 std::vector::emplace_back 就地构造对象而 std::vector::push_back 基本上复制对象(或原语类型)或将其移动到 vector 的末尾。

然后 std::vector::push_back 看起来是将原始类型添​​加到 std::vector 中的更好选择。例如:

std::vector<int> vVec;
vVec.push_back(10);
int iVar 30;
vVec.push_back(iVar);

但是当我们谈论对象时,我并不是很清楚。让我们以 std::string 的 vector 为例。如果我想添加文字字符串,我将使用 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_backstd::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 涉及调用自定义 string 构造函数,然后调用 move 构造函数,但 emplace_back 调用自定义 string 直接构造函数,保存对移动构造函数的调用。

std::string 的移动构造函数可能不是什么大问题,但是当对象没有有效的移动构造函数时,emplace 函数可以节省时间,并且可以即使类类型由于某种原因具有已删除的移动构造函数,也可以使用。 (好吧,如果删除移动和复制构造函数,std::vector 将不会高兴,但其他容器可以接受。)

关于c++ - push_back 与 emplace_back 到 std::vector<std::string>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43596430/

有关c++ - push_back 与 emplace_back 到 std::vector<std::string>的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

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

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

  3. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

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

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

  5. ruby - 从 String#split 返回的零长度字符串 - 2

    在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"

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

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby-on-rails - 没有参数的 `<<`(小于两倍)是什么意思? - 2

    我在一个我想在formtasticGem中覆盖的方法中找到了这个。该方法如下所示:defto_htmlinput_wrappingdohidden_field_html是什么意思?在第三行做什么?我知道它对数组有什么作用,但在这里我不知道。 最佳答案 你可以这样读:hidden_field_htmllabel_with_nested_checkbox是连接到hidden_​​field_html末尾的参数-为了“清晰”,他们将其分成两行 关于ruby-on-rails-没有参数的`

  9. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐