程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實戰c++中的vector系列--知道emplace_back為何優於push_back嗎?

實戰c++中的vector系列--知道emplace_back為何優於push_back嗎?

編輯:C++入門知識

實戰c++中的vector系列--知道emplace_back為何優於push_back嗎?


我們不把struct當做vector的元素了,我們把一個class當做vector的元素,寫下代碼:

#include 
#include 
#include
using namespace std;
class CText {
private:
    string str;
public:
    text(string s) :str(s) {
    }
    void show()const {
        cout << str << endl;
    }

};
int main()
{
    vector vi;
    vi.emplace_back("hey");
    vi.front().show();
    vi.push_back("girl");//錯誤
    vi.back().show();
    return 0;
}

其中vi.push_back(“girl”);這條語句錯誤,VS2015報錯為:

error C2664: “void std::vector>::push_back(const text &)”: 無法將參數 1 從“const char [5]”轉換為“text &&”

但此時我們稍作修改:
把 vi.push_back(“girl”) 改為
vi.push_back(CText(“girl”));
問題就解決了。。

簡而言之,就是empace_back與push_back相比,替我們省去了調用CText進行構造。

emplace_back
添加一個新元素到結束的容器。該元件是構成在就地,即沒有復制或移動操作進行。

inserts a new element at the end of the vector, right after its current last element. This new element is constructed in place using args as the arguments for its constructor.

This effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.

The element is constructed in-place by calling allocator_traits::construct with args forwarded.

A similar member function exists, push_back, which either copies or moves an existing object into the container.

寫到這裡,你應該明白emplace_back如何是也了吧。

最後再來一段代碼,涉及到使用右值引用和std::move的:

#include 
#include 
#include 

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) = default;
};

int main()
{
    std::vector
 elections;
    std::cout << "emplace_back:\n";
    elections.emplace_back("Nelson Mandela", "South Africa", 1994);

    std::vector
 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.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved