push_back & emplace_back

push_back & emplace_back

内容

在C++中,vector<vector<int>>使用push_backemplace_back时对初始化列表的处理差异源于两者参数传递机制的不同。以下是详细解释:


1. push_back的工作原理

  • 隐式类型转换
    push_back的参数类型是明确的const vector<int>&vector<int>&&。当传递{1, 2, 3}时,编译器会自动将其隐式转换为一个临时的vector<int>对象(调用vector<int>的构造函数接受std::initializer_list<int>)。

  • 代码示例

    std::vector<std::vector<int>> v;
    v.push_back({1, 2, 3});  // 等效于 v.push_back(std::vector<int>{1, 2, 3});
    

2. emplace_back的限制

  • 直接构造参数
    emplace_back的参数是直接传递给元素构造函数的一组参数。然而,初始化列表{1, 2, 3}的类型是std::initializer_list<int>,而vector<int>的构造函数需要显式接受这个类型。

  • 模板参数推导失败
    由于模板参数推导规则的限制,编译器无法将{1, 2, 3}推导为std::initializer_list<int>。因此,必须显式指明参数类型。

  • 正确写法

    v.emplace_back(std::initializer_list<int>{1, 2, 3});  // 显式传递初始化列表
    // 或直接构造临时对象
    v.emplace_back(std::vector<int>{1, 2, 3});
    

3. 根本原因

方法 参数类型 初始化列表处理
push_back const vector<int>&vector<int>&& 接受隐式转换,允许从{...}构造临时vector<int>
emplace_back 模板参数包(需匹配vector<int>的构造函数) 无法推导{...}std::initializer_list<int>

4. 解决方法

(1) 显式传递std::initializer_list<int>

v.emplace_back(std::initializer_list<int>{1, 2, 3});

(2) 使用直接构造临时对象

v.emplace_back(std::vector<int>{1, 2, 3});

(3) 使用C++17的类模板参数推导(CTAD)

在C++17及以上版本中,可以简化构造:

v.emplace_back(std::vector{1, 2, 3});  // 无需指定<int>

5. 性能对比

方法 内存操作 效率
push_back 构造临时vector<int> → 移动或拷贝到容器 可能有一次拷贝/移动
emplace_back 直接在容器内存中构造vector<int> 无临时对象开销

6. 总结

  • push_back的便捷性
    依赖隐式转换,适合快速插入已知类型的对象。

  • emplace_back的灵活性
    需显式传递构造参数,避免临时对象,但需注意模板参数推导的限制。

通过理解两者底层机制,可以更高效地选择适合场景的方法。

本文作者:Gold_stein

本文链接:https://www.cnblogs.com/smartljy/p/18748609

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Gold_stein  阅读(15)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 逃离地面 RAD & 三浦透子
逃离地面 - RAD & 三浦透子
00:00 / 00:00
An audio error has occurred.

作词 : 野田洋次郎

作曲 : 野田洋次郎

空飛ぶ羽根と引き換えに 繋ぎ合う手を選んだ僕ら

それでも空に魅せられて 夢を重ねるのは罪か

夏は秋の背中を見て その顔を思い浮かべる

憧れなのか、恋なのか 叶わぬと知っていながら

重力が眠りにつく 1000年に一度の今日

太陽の死角に立ち 僕らこの星を出よう

彼が眼を覚ました時 連れ戻せない場所へ

「せーの」で大地を蹴って ここではない星へ

行こう

もう少しで運命の向こう もう少しで文明の向こう

もう少しで運命の向こう もう少しで

夢に僕らで帆を張って 来たるべき日のために夜を超え

いざ期待だけ満タンで あとはどうにかなるさと 肩を組んだ

怖くないわけない でも止まんない

ピンチの先回りしたって 僕らじゃしょうがない

僕らの恋が言う 声が言う

「行け」と言う