精华内容
下载资源
问答
  • c++11 之emplace_back 与 push_back的区别

    万次阅读 多人点赞 2018-12-03 14:32:45
    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。...

    c++开发中我们会经常用到插入操作对stl的各种容器进行操作,比如vector,map,set等。在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题就是临时变量申请资源的浪费。 
    引入了右值引用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数,如果可以在插入的时候直接构造,就只需要构造一次即可。这就是c++11 新加的emplace_back。

    emplace_back函数原型:

    template <class... Args>
      void emplace_back (Args&&... args);
    

    在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。
    一个很有用的例子:

    #include <vector>  
    #include <string>  
    #include <iostream>  
    
    struct President  
    {  
        std::string name;  
        std::string country;  
        int year;  
    
        President(std::string p_name, std::string p_country, int p_year)  
            : name(std::move(p_name)), country(std::move(p_country)), year(p_year)  
        {  
            std::cout << "I am being constructed.\n";  
        }
        President(const President& other)
            : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
        {
            std::cout << "I am being copy constructed.\n";
        }
        President(President&& other)  
            : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  
        {  
            std::cout << "I am being moved.\n";  
        }  
        President& operator=(const President& other);  
    };  
    
    int main()  
    {  
        std::vector<President> elections;  
        std::cout << "emplace_back:\n";  
        elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创建  
    
        std::vector<President> reElections;  
        std::cout << "\npush_back:\n";  
        reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  
    
        std::cout << "\nContents:\n";  
        for (President const& president: elections) {  
           std::cout << president.name << " was elected president of "  
                << president.country << " in " << president.year << ".\n";  
        }  
        for (President const& president: reElections) {  
            std::cout << president.name << " was re-elected president of "  
                << president.country << " in " << president.year << ".\n";  
        }
    
    }
    

    输出

    emplace_back:
    I am being constructed.
    
    push_back:
    I am being constructed.
    I am being moved.
    
    Contents:
    Nelson Mandela was elected president of South Africa in 1994.
    

    网上有人说尽量使用emplace_back代替 push_back 有没有什么特例是不能替换的呢,搜了一下发现了一个例子:

    emplace_back造成的引用失效 

    勘误:window visual studio 2015 编译下面程序会出现 引用失效问题,而linux gcc 和qt 等编译环境中未出现下面问题。感谢大家的指正。

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> ivec;
        ivec.emplace_back(1);
        ivec.emplace_back(ivec.back());
        for (auto it = ivec.begin(); it != ivec.end(); ++it)
            cout << *it << " ";
        return 0;
    }
    
    //输出:
    1 -572662307 

    尝试1:不直接给emplace_back传递ivec.back():

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> ivec;
        ivec.emplace_back(1);
        auto &it = ivec.back();
        ivec.emplace_back(it);
        for (auto it = ivec.begin(); it != ivec.end(); ++it)
            cout << *it << " ";
        return 0;
    }
    输出:
    1 -572662307 

    尝试2:不给emplace_back传递引用:

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> ivec;
        ivec.emplace_back(1);
        auto it = ivec.back();
        ivec.emplace_back(it);
        for (auto it = ivec.begin(); it != ivec.end(); ++it)
            cout << *it << " ";
        return 0;
    }
    输出:
    1 1

    我们如愿以偿,这时候应该可以得到结论了,ivec.back()返回的是引用,但是这个引用失效了,所以才会输出不正确;我们之前也提到过,重新分配内存会造成迭代器的失效,这里是造成了引用的失效。

    再回头看看emplace_back的描述: 
    if a reallocation happens, all iterators, pointers and references related to this container are invalidated. 
    Otherwise, only the end iterator is invalidated, and all other iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

    进一步
    尝试3:避免emplace_back引起重新分配内存:

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> ivec;
        ivec.reserve(4);
        ivec.emplace_back(1);
        ivec.emplace_back(ivec.back());
        for (auto it = ivec.begin(); it != ivec.end(); ++it)
            cout << *it << " ";
        return 0;
    }
    输出:
    1 1


    参考链接:

    https://blog.csdn.net/windpenguin/article/details/75581552 

    https://blog.csdn.net/xiaolewennofollow/article/details/52559364 

    https://blog.csdn.net/wangshubo1989/article/details/50358044 

    展开全文
  • emplace_back() 和 push_back 的区别

    万次阅读 多人点赞 2016-09-17 00:05:42
    emplace_back()

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题是临时变量申请的资源就浪费。
    引入了右值引用,转移构造函数(请看这里)后,push_back()右值时就会调用构造函数和转移构造函数。
    在这上面有进一步优化的空间就是使用emplace_back

    emplace_back

    函数原型:

    template <class... Args>
      void emplace_back (Args&&... args);

    在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。
    给出一个示例,这个示例很有用。

    #include <vector>  
    #include <string>  
    #include <iostream>  
    
    struct President  
    {  
        std::string name;  
        std::string country;  
        int year;  
    
        President(std::string p_name, std::string p_country, int p_year)  
            : name(std::move(p_name)), country(std::move(p_country)), year(p_year)  
        {  
            std::cout << "I am being constructed.\n";  
        }
        President(const President& other)
            : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
        {
            std::cout << "I am being copy constructed.\n";
        }
        President(President&& other)  
            : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  
        {  
            std::cout << "I am being moved.\n";  
        }  
        President& operator=(const President& other);  
    };  
    
    int main()  
    {  
        std::vector<President> elections;  
        std::cout << "emplace_back:\n";  
        elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创建  
    
        std::vector<President> reElections;  
        std::cout << "\npush_back:\n";  
        reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  
    
        std::cout << "\nContents:\n";  
        for (President const& president: elections) {  
           std::cout << president.name << " was elected president of "  
                << president.country << " in " << president.year << ".\n";  
        }  
        for (President const& president: reElections) {  
            std::cout << president.name << " was re-elected president of "  
                << president.country << " in " << president.year << ".\n";  
        }
    
    }
    

    输出

    emplace_back:
    I am being constructed.
    
    push_back:
    I am being constructed.
    I am being moved.
    
    Contents:
    Nelson Mandela was elected president of South Africa in 1994.
    展开全文
  • C++ - "emplace_back" 和 "push_back" 的区别

    万次阅读 多人点赞 2013-10-23 09:58:02
    "emplace_back"和"push_back"的区别 emplace_back和push_back都是向容器内添加数据. 对于在容器中添加类的对象时, 相比于push_back, emplace_back可以避免额外类的复制和移动操作. "emplace_back avoids the extra ...

    "emplace_back" 和 "push_back" 的区别

    emplace_backpush_back都是向容器内添加数据.

    对于在容器中添加类的对象时, 相比于push_back,emplace_back可以避免额外类的复制和移动操作.

    "emplace_back avoids the extra copy or move operation required when using push_back."

    参见: http://en.cppreference.com/w/cpp/container/vector/emplace_back

    注意下面代码中的emplace_back和push_back的添加方式(VS2012下编译通过):

     

    #include <vector>
    #include <string>
    #include <iostream>
    
    struct President
    {
    	std::string name;
    	std::string country;
    	int year;
    
    	President(std::string p_name, std::string p_country, int p_year)
    		: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    	{
    		std::cout << "I am being constructed.\n";
    	}
    	President(President&& other)
    		: name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    	{
    		std::cout << "I am being moved.\n";
    	}
    	President& operator=(const President& other);
    };
    
    int main()
    {
    	std::vector<President> elections;
    	std::cout << "emplace_back:\n";
    	elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创建
    
    	std::vector<President> reElections;
    	std::cout << "\npush_back:\n";
    	reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
    
    	std::cout << "\nContents:\n";
    	for (President const& president: elections) {
    		std::cout << president.name << " was elected president of "
    			<< president.country << " in " << president.year << ".\n";
    	}
    	for (President const& president: reElections) {
    		std::cout << president.name << " was re-elected president of "
    			<< president.country << " in " << president.year << ".\n";
    	}
    }


    展开全文
  • push_back

    2020-09-08 10:17:04
    push_back是编程语言里面的一个函数名。如c++中的vector头文件里面就有这个push_back函数,在vector类中作用为在vector尾部加入一个数据。

    push_back是编程语言里面的一个函数名。如c++中的vector头文件里面就有这个push_back函数,在vector类中作用为在vector尾部加入一个数据。

    展开全文
  • c++ emplace_back与push_back

    2021-01-08 02:10:39
    容器的emplace_back与push_back方法 emplace_back针对添加的元素为 “某个对象struct、class” ,可以直接写参数,函数自动调用构造函数,而不用先创建对象再添加。 push_back需要先创建对象,再添加。 emplace、...
  • C++ 中”emplace_back” 与 “push_back” 的区别 emplace_back和push_back都是向容器内添加数据. 对于在容器中添加类的对象时, 相比于push_back,emplace_back可以避免额外类的复制和移动操作. “emplace_back ...
  • 本篇学习list添加元素操作 push_back:将元素添加到容器末尾 emplace_back:在容器末尾就地构造元素 push_front:插入元素到容器起始 emplace_front:在容器头部就地构造元素 resize:改变容器中可存储元素的个数
  • c++ push_back与emplace_back

    2021-04-15 11:28:32
    push_back与emplace_back 本节直接讨论在向容器添加数据时,插入(push_back、push_front、insert等)和置入(emplace_back)的内存性能情况,深入了解C++的内部机制。考虑下面代码: vector<string> vs; vs.push_...
  • 上一篇博客说道vector中放入struct,我们先构造一个struct对象,再push_back。那段代码中,之所以不能使用emplace_back,就是因为我们定义的struct没有显示的构造函数。emplace和解? 放列的意思。这次我们不把...
  • 可参考:C++中push_back和emplace_back的区别 最好再结合push_back()传参的变化过程了解下: 对于push_back()而言,最开始只有void push_back( const T& value );这个函数声明,后来从C++11,新加了void ...
  • C++中push_back,push_front,insert的用法

    千次阅读 2018-09-15 15:37:34
    之前在介绍vector的初始化的时候有介绍到容器的push_back操作,push_back基本所有容器都支持,而push_front则是有的支持有的不支持。insert和push_back一样都支持...
  • push_back和emplace_back的区别 如果push_back传入左值 调用构造函数和拷贝构造函数 如果push_back传入右值 调用构造函数和移动构造函数 但是调用emplace_back,只调用构造函数 总结,在C++11以后,emplace_...
  • push_back:在队列末尾添加一个元素,参数为拷贝或移动的元素 emplace_back c++11 :在队列尾部添加一个元素 push_front :在队列头部添加一个元素,参数可以是拷贝或移动的元素 emplace_front c++11 :在队列头部...
  • 新版本的原型展示: void push_back(const value_type& x); void push_back(value_type&& x); <typename… Args> reference emplace_back(Args&&… args); 两者区别:push_back传入一个...
  • list.push_back在链表的最后插入 list.push_front在链表的首位插入 #include<iostream> #include<list> using namespace std; int main() { list <int> a; list <int>::iterator Iter...
  • vector中push_back和emplace_back区别区别测试代码vector空间自动增长代码 正常情况下push_back是往vector中添加新的元素,只不过添加过程是先利用拷贝构造函数复制目标值,而 emplace_back可以 直接在目标位置上...
  • 在C11中,有两种方法可以把元素放入容器中:emplace_back和push_backpush_back是C11之前就有的,而emplace_back是C11中新加的。 既然它们的作用都是一样的,那么为什么C11中又加入了一个emplace_back? 既生瑜,何...
  • push_back vs emplace_back 总结: push_back分为两步:先创建一个临时的构造器,然后将这个临时构造器移动或者拷贝到目标容器中。 emplace_back仅有一步:直接在目标容器的目标位置,原地创建构造器即可,无需移动...
  • 之前在介绍vector的初始化的时候有介绍到容器的push_back操作,push_back基本所有容器都支持,而push_front则是有的支持有的不支持。insert和push_back一样,所有容器都支持。 这里简单介绍一下三种不同添加元素的...
  • C++中push_back()函数

    万次阅读 多人点赞 2019-07-21 14:02:29
    push_back()函数的用法 函数将一个新的元素加到vector的最后面,位置为当前最后一个元素的下一个元素 push_back() 在Vector最后添加一个元素(参数为要插入的值) //在vec尾部添加10 vector<int> vec; ...
  • 主要介绍了C++ 中"emplace_back" 与 "push_back" 的区别的相关资料,需要的朋友可以参考下
  • 转自:问题: 将N个元素使用push_back插入到vector中, 求push_back操作的复杂度。 参考:C++ std::vector中push_back操作时间复杂度分析 分析如下: 考虑vector每次内存扩充两倍的情况: 如果我们插入N个元素,则...
  • vec.push_back(std::pair<:global_dof_index double>()); vec.push_back(std::pair<:global_dof_index double>(dof, var)); </:global_dof_index></:global_dof_index></:pair>...
  • emplace操作是C++11新特性,新引入的三个操作emplace_front、emplace 和 emplace_back,分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部[1]。 本文以emplace_back和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,785
精华内容 6,714
关键字:

push_back