首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么向量emplace调用复制构造函数,而set不调用复制构造函数?

向量(Vector)是一种动态数组,可以在其末尾高效地插入和删除元素。emplace_back() 是向量的一个成员函数,用于在向量末尾直接构造元素。当调用emplace_back()时,会根据传入的参数直接在向量的末尾构造一个新元素,而不是先创建一个临时对象然后再进行拷贝构造。这样做可以节省拷贝构造的开销,提高性能。

而集合(Set)是一种有序的容器,其中的元素是唯一的。在集合中插入新元素时,set会先创建一个临时对象,然后再进行拷贝构造到集合中。这是因为集合中的元素需要保持有序,因此无法直接在集合中构造元素。

总结起来,向量中使用emplace_back()是为了高效地构造元素,而集合中使用拷贝构造函数是为了维持有序性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

关于Java构造函数(Constructor)的常见问题总结1 为什么调用子类的构造方法的时候,默认会调用父类的构造方法2 常见错误:Implicit super constructor is und

1 为什么调用子类的构造方法的时候,默认会调用父类的构造方法 看下面这个简单的例子: package cc; public class Sub extends Super { public Sub...这就是为什么我们上面的那个例子程序会先调用super的构造方法。 但要切记,** 虽然调用了父类的构造方法,但只创建了一个对象也就是子对象。...解决这个问题很简单,我们可以给父类插入一个无参的构造函数,或者在子类构造函数中显示的调用的父类有参构造函数。 在子类的构造函数中显示的调用父类的构造函数 下面的代码是正确的。 ?...为什么Java在一个类已经实现了一个带参的构造函数的时候,不实现默认的无参构造函数? 这是个很有趣的问题。...我们知道如果在一个类中没有声明一个构造函数,那么编译器会隐式的帮我们实现一个无参的构造函数,但如果我们一旦一个构造函数,不管带不带参数,那么编译器都不会提供默认的构造函数,所以这么做的原因是为什么呢?

2.7K41

创建子类对象时,父类构造函数调用被子类重写的方法为什么调用的是子类的方法?

public static void main(String[] args) { A a = new A(); B b = new B(); } } 问题:为什么创建...A对象的时候父类会调用子类方法?...但是:创建B对象父类会调用父类的方法? 答案: 当子类被加载到内存方法区后,会继续加载父类到内存中。...当子类对象创建时,会先行调用父类的构造方法(构造方法也是方法),虚拟机会在子类方法区寻找该方法并运行。 但是:由于java语言是静态多分派,动态单分派。...其结果是当编译的时候,父类构造方法调用的方法的参数已经强制转换为符合父类方法的参数了。 上边代码在编译前已经转换为下面这个样子的了。

6.1K10

现代C++之容器

建议在接口中使用const string&,除非确知调用者已经持有 string:如果函数里不对字符串做复杂处理的话,使用 const char* 可以避免在调用者只有 C 字符串时编译器自动构造 string...后者是最理想的情况,因为即使在只有 C 字符串的情况,也不会引发不必要的内存复制。 如果需要在函数内修改字符串内容、但不影响调用者的该字符串,使用 string 作为参数类型(自动拷贝)。...2.vector 2.1 异常安全性 vector 通常保证强异常安全性,如果元素类型没有提供一个保证抛异常的移动构造函数,vector 通常会使用拷贝构造函数。...4.queue与stack (1)为什么 stack(或 queue)的 pop 函数返回类型为 void,不是直接返回容器的 top(或 front)成员?...因为 stack(queue)为保证强异常安全性,如果元素类型没有提供一个保证抛异常的移动构造函数, 通常会使用拷贝构造函数

1K10

C++(STL):19---deque之删除和emplace用法

成员函数 功能 push_back() 在容器现有元素的尾部添加一个元素,和 emplace_back() 不同,该函数添加新元素的过程是,先构造元素,然后再将该元素移动或复制到容器的尾部。...emplace_back() C++ 11 新添加的成员函数,其功能是在容器尾部生成一个元素。和 push_back() 不同,该函数直接在容器头部构造元素,省去了复制或移动元素的过程。...和 emplace() 不同的是,该函数添加新元素的过程是,先构造元素,然后再将该元素移动或复制到容器的指定位置。...: 调用构造函数 调用移动构造函数 emplace_front: 调用构造函数 push_front: 调用构造函数 调用移动构造函数 emplace_back: 调用构造函数 push_back: 调用构造函数...调用移动构造函数 可以看到,相比和它同功能的函数emplace 系列函数都只调用构造函数没有调用移动构造函数,这无疑提高了代码的运行效率。

1.3K40

深入浅出list容器

list接口的使用 构造函数 构造函数 接口说明 list(size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素...:直接在容器末尾的空间内构造元素,不需要先复制或移动。...emplace_back:对于复杂类型,使用 emplace_back 可以避免复制或移动操作,直接在容器末尾构造元素,从而提高性能。...,运行如下: 可以发现,在使用emplace_back(3, 3)的时候会直接进行构造不会像使用push_back一样先构造出一个对象,再拷贝构造进行插入。...emplace_back 通常在需要构造复杂类型或避免不必要的复制和移动操作时更优, push_back 在添加简单类型或已经存在的元素时更为方便。 通过重载再次理解->与.

7110

再也不用std::thread编写多线程了

,所以它的析构函数将表现为常规行为 //但是 std::packsgaed_task不能复制,将pt传递给 std::thread的构造函数一定要将它强制转型到右值 std::thread...* * c++98中肯定会发生的,无论调用方传入的是什么,形参newName都会经过复制构造函数创建 * * 不过,在C++11中,newName仅在传入左值时候才会被复制构造,若传入右值,会被移动构造...newName的成本 //如果采用了按引用途径,就不会有这种问题 //如果采用赋值来实施形参复制的话,情况更复杂了!...之后,会在内存中为 std::vector构造一个 x的副本 * ,这是第二次的构造,它的结果在 std::vector内创建了一个新的对象 (用来将 x复制到 std::vector中的构造函数,是移动构造函数...优点:置入接受的是待插入对象的构造函数实参,避免临时对象的创建和析构,插入接受的是待插入对象,无法避免 * * * * @return int */ //同样,即使插入函数并不要求创建临时对象的情况,

2.4K40

终于弄明白了万能引用和右值引用的区别

第5章 右值引用,移动语义和完美转发 /** 几个概念: 1,移动语义:使用移动操作替换复制操作,比如移动构造函数和移动赋值运算符替换复制构造函数复制赋值运算符 移动语义使得创建只移动型别对象成为可能...const std::string , 强制转换得结果是个右值 const std::string 再看一下 string得构造函数 class stringStr{ public:...,因为移动构造函数只能接受非常量 std::string型别得右值引用作为形参 2,这个右值可以传递给复制构造函数,因为指涉到常量得左值引用允许绑定到一个常量右值型别得形参 */ };...process的右值版本 */ } //场景2:推荐 std::forward 推荐 std::move //一个类,用它进行移动构造函数调用次数的跟踪 //使用std::move...为什么short传给万能引用却报错呢?

1.8K10

重温C++的设计思想

局限性在现代处理器架构上是绝对有优势,缺点是复制对象的开销大大增加,所以C++需要移动语义,Java里根本没有。...实现operator=函数。 三、容器 3.1 连续内存的vector容器 vector保证强异常安全性,如果元素类型没有提供一个保证抛异常的移动构造函数,vector使用拷贝构造函数。...如果自定义类型拷贝构造代价较高,则使用移动构造函数,并标其为noexcept,或者只在容器中放置对象的智能指针。 C++11提供的emplace系列函数,是为了提升容器性能设计。...emplace_back比push_back 少额外生成临时对象,少一次拷贝构造和一次析构。 现代处理器架构对连续内存访问速度比连续内存访问速度快很多,所以vector的连续内存是他的优点。...set和multiset只存放键,map和multimap存放键值对。与序列容器相比,关联容器没有前、后的概念。但是提供insert、emplace函数

1.6K247

实用编程技巧汇总,让代码效率提高一个档次

;而定义在外部每次循环只需要调用复制构造函数。...inline、const、&修饰符 inline让函数内联,建议编译器将函数体代码“复制粘贴”到函数调用处,在函数体短小,函数调用又比较频繁的时候能有效避免因函数调用带来的内存开销(因为每一次调用函数系统都会生成许多额外的变量...在for循环中的频繁自增操作中,创建临时迭代器temp,以及返回temp时调用复制构造函数所需的时间不容忽视。...由于要重新分配大量内存以及反复调用复制构造函数,这对时间和空间的开销是巨大的。 为了减少内存的重新分配,我们可以适当的估计我们需要保存的元素数量,并在vector初始化的时候指定其capacity。...由于指针相对于其所指向的对象来说占用内存很小,而且在复制的时候不用调用复制构造函数,因此以上提到的一些缺点都能很好的克服。

67420

深入理解 C++ 右值引用和移动语义:全面解析

class和struct)自动生成的4个函数,分别是构造函数,拷贝构造函数,赋值运算符重载函数和析构函数。...虽然通过传引用的方式,可以避免对象的复制。但是还是没法避免上述的临时对象的复制移动语义成功的解决的这个问题。...移动的本质就是获取临时对象的所有权,不是通过复制的方式来获得。...如果是右值,就调用移动构造或移动赋值运算符函数。当Foo是一个很大的对象时候,就会极大的降低开销,提高程序效率。...的大部分组件都支持移动语义,比如vector,string等即可以通过move转换右值后调用移动构造函数进行移动操作来避免深拷贝。

1.6K20

C++(STL):34--- multiset容器详解

值得一提的是,multiset 类模板提供的构造函数,和 set 类模板中提供创建 set 容器的构造函数,是完全相同的。...multiset 类模板中提供了 5 种构造函数,也就代表有 5 种创建 multiset 容器的方式,分别如下。 1) 调用默认构造函数,创建空的 multiset 容器。...3) multiset 类模板中还提供了拷贝(复制构造函数,可以实现在创建新 multiset 容器的同时,将已有 multiset 容器中存储的所有元素全部复制到新 multiset 容器中。...multiset 容器,因此在初始化 copymultiset 容器时,其内部调用的是 multiset 类模板中的移动构造函数,而非拷贝构造函数。...显然,无论是调用复制构造函数还是调用拷贝构造函数,都必须保证这 2 个容器的类型完全一致。

1.1K20

C++ set用法大全

今天咱们继续来聊聊C++中的set。 上次的文章遗留了一个问题没有回答,有些小伙伴有些疑问。就是为什么set是关联式的容器,这个关联体现在哪里。...除了这三种形式的构造函数之外,还可以利用set类模板的第二个参数,传入元素排序规则来影响set中元素的排序,这勉强也算是一种构造方法: set> st{"...insert insert函数非常简单,就直接调用,往set里插入即可。...P p{0, 3}; st.insert(p); 如果使用emplace函数呢,则是这样: st.emplace(1, 23); 因为emplace的内部会替我们去调用结构体P的构造函数,使用1和23...如果插入成功则返回新添加的元素,否则则指向set容器中和添加元素相同的元素。 使用emplace_hint会影响set中的有序性,一般建议使用。

3.7K10

C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

部分传返回值的问题(非局部对象):在函数返回一个临时对象时,如果返回类型是一个对象不是引用或指针,会导致拷贝构造函数调用,产生额外的开销。...这意味着内置类型的值会被直接复制或返回,不需要调用拷贝构造函数。...直接构造函数的前提是直接传入参数,不是现成的对象或者匿名对象 与 push_back() 的区别 push_back() 接受一个对象的副本(拷贝或移动), emplace_back() 直接在容器中构造对象...(Date(2023, 1, 1)); return 0; } 对于使用 emplace_back() 或者 emplace 系列函数来直接在容器中构造对象的情况,需要传入构造函数所需的参数,不是现成的对象或者匿名对象...,它可以用来存储、复制调用任何可调用对象,包括函数指针、函数对象、Lambda表达式等。

7200

双端队列和C++ std::deque详解

shrink_to_fit函数主要是用来请求移除未使用的容量,通过释放未使用的内存来减少对内存的使用,但其是减少使用内存更改序列大小的非强制请求,其请求是否达成依赖于具体实现。...emplace函数的声明如下: /*---------------------------------- pos:将构造新元素到其前的迭代器 args:转发给元素构造函数的参数 返回值iterator...函数emplace类似,只不过是在容器末尾就地构造元素,其函数声明如下: template< class......( T&& value ); //C++11 起 emplace_front emplace_front函数的作用是在容器头部原位构造元素,即插入新元素到容器起始,由于其也是在容器所提供的位置原位构造函数...deque容器的内容,不在单独的元素上调用任何移动、复制或交换操作。

55220

【Example】C++ 标准库常用容器全面概述

vector 所用的方式不在每次插入元素时,只在额外内存耗尽时重分配。分配的内存总量可用 capacity() 函数查询。额外内存可通过对 shrink_to_fit() 的调用返回给系统。 ...operator= 用另一个vector的副本替换该向量中的元素。...以较小的大小调用 resize 不会非法化任何到未擦除元素的引用。 以较大的大小调用 resize 不会非法化任何到 deque 元素的引用。...get_allocator 返回用于构造 allocator 的 set 对象的副本。 insert 将一个元素或元素范围插入到set。...(const修饰) emplace 将原位构造的元素插入到Map中。 emplace_hint 将原位构造的元素插入到Map中,且尽可能于 hint(迭代器) 前面位置。 empty 判断是否为空。

3.3K30

C++17,optional, any, 和 variant 的更多细节

,这意味着 std::optional 的构造参数将直接用于调用 std::string 的构造函数.所以在上述代码中, opt1 中 std::string 的构造函数参数即为 C 风格字符串(“C+...::optional 的复制构造函数(复制了op3)....其实早在 C++11 中,标准库容器就引入很多用于增加容器元素的接口方法,这些方法都以 emplace 开头,功能上就是提供了就地构造的方法.以 std::vector vec 为例,借助其支持的...emplace_back 方法,我们可以直接调用 vec.emplace_back(5) 来增加 vec 的末尾元素,这等同于下面代码: vec.push_back(int(5)). std::variant...类型,是一种可以被调用的类型,通常是一个函数,一个函数对象或者一个 lambda 函数.简单起见,这里我仅使用 lambda 函数来举例说明.

2.3K20

stack的使用以及模拟实现

()的区别 在STL中,push()和emplace()都是向容器中添加一个元素,但是它们有以下不同: 1.① push()只能将一个已经创建的对象压入容器中,并且该对象的副本被创建,因此需要调用拷贝构造函数...②emplace()直接在容器中创建一个新对象,因此不需要调用拷贝构造函数创建副本....push()方法需要传递一个已经创建好的对象,emplace()方法需要传递的是要创建对象的构造函数参数。...从上面来看emplace()方法更高效,因为它直接在容器中创建一个新对象,不是创建一个临时对象并将其复制到容器中。因此,在需要创建大量对象的情况下,emplace()方法比push()方法更适合。...如今,C++不仅不用手动造轮子,还会自动调用析构和构造函数. 试着练练手吧!

18030
领券