0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

emplace

分享:

好的!关于 emplace(中文常译为 “就地构造”“放置”),它是一个在编程中(尤其是在 C++ 标准模板库 中)非常重要的概念和函数家族。它的核心目的是 直接在容器内部构造对象,避免不必要的临时对象创建和拷贝/移动操作,从而提高效率

以下是详细解释:

  1. 核心思想:

    • 传统的添加元素方法(如 push_back, insert)通常需要先在容器外部构造好一个完整的对象,然后将这个对象拷贝或移动到容器内部。
    • emplace 系列函数(如 emplace_back, emplace, emplace_front)则不同。它们接受的是构造新元素所需的参数列表(构造函数参数),而不是一个构造好的对象。
    • STL 容器会在容器内部预留的内存位置上,直接使用这些参数来调用构造函数创建新元素。
  2. 主要优势:

    • 避免额外开销: 省去了在外部创建临时对象的过程,也省去了将这个临时对象拷贝或移动到容器内部的成本(即使移动语义比拷贝快,也可能有开销)。
    • 支持不可拷贝/不可移动的类型: 对于既不能拷贝也不能移动的对象类型(例如,包含 std::mutex 的类),传统的 push/insert 无法使用,而 emplace 可以直接在容器内部构造它们。
    • 效率更高: 尤其对于构造过程复杂或对象较大的类型,emplace 通常能带来显著的性能提升。
  3. 常见 emplace 函数:

    • emplace_back(args...)std::vector, std::deque, std::list 等序列容器的末尾就地构造一个新元素。替代 push_back
    • emplace_front(args...)std::deque, std::list, std::forward_list开头就地构造一个新元素。替代 push_front
    • emplace(hint, args...) 在关联容器(如 std::map, std::set, std::unordered_map, std::unordered_set)中或序列容器的指定位置(如果有提示迭代器 hint)就地构造一个新元素。替代 insert
    • emplace_hint(hint, args...) 主要用于关联容器,提供位置提示以优化插入效率。就地构造元素。
  4. push/insert 的对比:

    操作 所需参数 发生拷贝/移动? 可处理不可拷贝/移动类型? 典型效率
    container.push_back(value) 一个构造好的 value 对象 (拷贝或移动 value 进容器) 较低 (可能涉及拷贝/移动)
    container.push_back(T(arg1, arg2)) 一个构造好的临时 T 对象 (移动临时对象进容器) 中等 (涉及临时对象构造和移动)
    container.emplace_back(arg1, arg2) 构造 T 所需的参数 arg1, arg2 (直接在容器内调用 T(arg1, arg2)) 较高 (避免临时对象和拷贝/移动)
  5. 简单示例 (C++):

    #include 
    #include 
    
    struct Point {
        double x, y;
        Point(double a, double b) : x(a), y(b) {
            std::cout << "Constructing Point(" << x << ", " << y << ")\n";
        }
        // 假设这个类很大或者拷贝/移动成本高,或者甚至删除了拷贝/移动构造函数/赋值运算符
    };
    
    int main() {
        std::vector points;
    
        // 传统方法 1: 外部构造 + 拷贝 (如果定义了拷贝构造函数)
        Point p1(1.0, 2.0);
        points.push_back(p1); // 可能调用拷贝构造函数 (如果未优化)
    
        std::cout << "----\n";
    
        // 传统方法 2: 构造临时对象 + 移动 (C++11起)
        points.push_back(Point(3.0, 4.0)); // 调用构造函数创建临时对象,然后移动它 (移动构造函数)
    
        std::cout << "----\n";
    
        // emplace 方法: 直接在 vector 内部内存构造
        points.emplace_back(5.0, 6.0); // 只调用一次构造函数!在 vector 内部构造 Point(5.0, 6.0)
    
        return 0;
    }

    可能的输出:

    Constructing Point(1, 2)  // 构造 p1
    (可能调用 Point 的拷贝构造函数) // 如果 push_back(p1) 没有被编译器优化 (RVO/NRVO)
    ----
    Constructing Point(3, 4)  // 构造临时对象
    (调用 Point 的移动构造函数)     // 移动临时对象进 vector
    ----
    Constructing Point(5, 6)  // 直接在 vector 内部构造!无额外拷贝/移动
  6. 何时使用?

    • 当向容器中添加新元素(而不是添加现有对象)时,优先考虑使用 emplace 系列函数 (emplace_back, emplace, emplace_front)。
    • 当对象类型构造代价高对象很大不可拷贝/不可移动时,强烈推荐使用 emplace
    • 添加已有的对象时,push_backinsert(有时配合 std::move)可能更直接。

总结:

emplace 是 C++ STL 提供的一种高效地在容器内部直接构造新元素的机制。它通过接收构造函数参数代替接收已构造对象避免了创建临时对象和后续的拷贝或移动操作,从而提升了性能,并支持处理不可拷贝/不可移动的类型。在需要向容器中添加新元素时,优先考虑 emplace_back, emplace, emplace_front 等函数通常是一个好的实践。这个概念在其他支持类似“放置构造”的语言或库中也可能存在。

ESP8266 Arduino库中std::map的问题如何解决?

:全选items.at(\"key\")=\"value\"; 或者 代码:全选items.emplace(\"key\",\"value\"); 所有导致相同的结果: 有人知道如何解决吗?

ytrwv 2023-06-08 06:38:28

OpenHarmony 3.2 Beta多媒体系列——音视频播放框架

;void PlayerDemo::RegisterTable()&#123; (void)playerTable_.emplace("prepare", std::bind

OpenHarmony开发者 2022-11-22 10:54:05

深度剖析OpenHarmony AI调度管理与推理接口

;ModelPathInfo&amp;gt; modelPaths; modelPaths.emplace_back(modelPathInfo

一只耳朵怪 2022-03-25 11:15:36

OpenHarmony 3.2 Beta多媒体系列——视频录制

;supportedCameras.emplace_back(cameraObj);&#125; &#125; else &#123;MEDIA_ERR_LOG("CameraManager

OpenHarmony开发者 2023-02-09 15:47:03

OpenHarmony相机用户态驱动框架

);waitingList_.emplace_back(request); // 捕获请求添加到waitingListcv_.notify_one(); } return RC_OK;}看看StreamStream是怎么实现的吧

jf_64661742 2022-04-20 17:09:41

OpenHarmony标准系统开机时长优化

: handles) &#123;threads.emplace_back(thread_func, handle); &#125; for (auto&amp; thread

OpenHarmony开发者 2023-04-10 10:22:08

Native Rawfile开发指导

); tempArray.emplace_back(filename); } napi_value fileList; napi_create_array(env, &amp;fileList

HarmonyOS开发者社区 2023-12-11 16:28:04

OpenHarmony 3.1 Release版本关键特性解析——OpenHarmony新音***引擎——HiStreamer

definition.protocol.emplace_back(ProtocolType::FILE); definition.creator = FileSourcePluginCreator; return reg-&amp;gt

OpenHarmony开发者 2022-06-01 17:41:09

【Milk-V Duo 开发板免费体验】RoboMaster机器人装甲板的识别

); armors.emplace_back(armor); break; } } return armors; } void adjustRec(cv::RotatedRect&amp; rec) { using

zealsoft 2023-07-28 20:23:01

HarmonyOS:Neural Network Runtime对接AI推理框架开发指导

; i++) { availableDevice.emplace_back(devices[i]); } } 在指定的设备上编译模型。 Neural Network Runtime 使用抽象的模型表达描述

HarmonyOS开发者社区 2023-12-19 10:09:16

加载更多
相关标签