在引入右值引用,轉移構造函數,轉移複製運算符以前,一般使用push_back()向容器中加入一個右值元素(臨時對象)的時候,首先會調用構造函數構造這個臨時對象,而後須要調用拷貝構造函數將這個臨時對象放入容器中。原來的臨時變量釋放。這樣形成的問題是臨時變量申請的資源就浪費。
引入了右值引用,轉移構造函數(請看這裏)後,push_back()右值時就會調用構造函數和轉移構造函數。
在這上面有進一步優化的空間就是使用emplace_backcss
函數原型:html
template <class... Args>
void emplace_back (Args&&... args);
在容器尾部添加一個元素,這個元素原地構造,不須要觸發拷貝構造和轉移構造。並且調用形式更加簡潔,直接根據參數初始化臨時對象的成員。
給出一個示例,這個示例頗有用。ios
#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";
}
}
輸出ide
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.