泰尹俊 2024-09-11 14:50 采纳率: 100%
浏览 7
已结题

C++ emplace_back vs push_back

C++ vector的emplace_back 与 push_back效率问题

#include <vector>
#include <functional>
#include <iostream>

class A
{
public:
    A(){printf("A()\n");}
    A(const A&) {printf("A copy\n");}
    ~A(){printf("~A()\n")}
};

int main()
{
    A a;
    std::vector<std::function<void()>> af;
    af.push_back([a](){});  //a被拷贝两次
    //af.emplace_back([a](){});  //a被拷贝三次
}

C++教程里emplack_back对比push_back会减少拷贝,但为何这里emplace_back会比push_back多一次拷贝

  • 写回答

1条回答 默认 最新

  • 月下独码 Java领域新星创作者 2024-09-11 16:16
    关注

    在您提供的代码示例中,emplace_backpush_back的行为与C++教程中描述的情况不符,这是因为您对lambda表达式的捕获方式有误解。

    首先,我们来澄清一下emplace_backpush_back的区别:

    • push_back接受一个值,这个值会被拷贝到vector的当前末尾。
    • emplace_back接受一个构造函数的参数列表,并在vector的当前末尾直接构造一个对象。

    在您的代码中,当您使用push_back时,您实际上是在创建一个std::function<void()>对象,它内部包含一个指向A的引用。这个引用会被拷贝到vector中,因此您看到了A copy的输出。

    对于emplace_back,由于您传递的是一个lambda表达式[a](){},这里有一个常见的误解。Lambda表达式默认捕获外部作用域中的变量是按值捕获的。这意味着a被拷贝了一次,并且lambda表达式内部存储的是a的一个拷贝。

    这里是问题的核心:

    af.push_back([a](){});  // a被拷贝两次
    // af.emplace_back([a](){});  // a被拷贝三次
    
    • push_back([a](){}); 这里的[a]是一个拷贝捕获,a被拷贝到lambda表达式中,然后这个lambda表达式被拷贝到vector中。所以这里实际上是有两次拷贝:一次是创建lambda表达式,另一次是将lambda表达式添加到vector中。
    • emplace_back([a](){}); 这里[a]同样是一个拷贝捕获,但是emplace_back直接在vector的末尾构造了lambda表达式。这里并没有额外的拷贝,因为lambda表达式是在vector内部构造的。

    所以,实际上emplace_back并不会比push_back多一次拷贝。如果您看到了emplace_backpush_back多一次拷贝的情况,那可能是因为其他原因,比如在打印消息时的输出顺序或者对lambda捕获的误解。

    总结一下,在这个特定的例子中,push_backemplace_back的行为应该是相同的,都涉及两次拷贝:一次是创建lambda表达式,另一次是将lambda表达式添加到vector中。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月20日
  • 已采纳回答 9月12日
  • 创建了问题 9月11日

悬赏问题

  • ¥15 preLaunchTask"C/C++: aarch64- apple-darwin22-g++-14 生成活动 文件”已终止,退出代码为-1。
  • ¥18 关于#贝叶斯概率#的问题:这篇文章中利用em算法求出了对数似然值作为概率表参数,然后进行概率表计算,这个概率表是怎样计算的呀
  • ¥20 C#上传XML格式数据
  • ¥15 elementui上传结合oss接口断点续传,现在只差停止上传和继续上传,各大精英看下
  • ¥100 单片机hardfaulr
  • ¥20 手机截图相片分辨率降低一半
  • ¥50 求一段sql语句,遇到小难题了,可以50米解决
  • ¥15 速求,对多种商品的购买力优化问题(用遗传算法、枚举法、粒子群算法、模拟退火算法等方法求解)
  • ¥100 速求!商品购买力最优化问题(用遗传算法求解,给出python代码)
  • ¥15 虚拟机检测,可以是封装好的DLL,可付费