[英]Initialize vector without copying and using move semantics
有沒有辦法在初始化向量時避免復制?
下面的代碼將產生以下 output。
#include <iostream>
#include <vector>
using namespace std;
struct Ticker {
std::string m_ticker;
Ticker() {
std::cout << "Default constructor" << std::endl;
}
Ticker(const std::string& ticker)
: m_ticker(ticker)
{
std::cout << "Parametrized constructor" << std::endl;
}
Ticker(Ticker&& other)
{
std::cout << "Move constructor" << std::endl;
m_ticker = other.m_ticker;
other.m_ticker = "";
}
Ticker(const Ticker& x)
{
std::cout << "Copy constructor" << std::endl;
m_ticker = x.m_ticker;
}
~Ticker()
{
std::cout << "Destructor" << std::endl;
}
friend std::ostream& operator << (std::ostream& os, const Ticker& dr);
};
std::ostream& operator << (std::ostream& os, const Ticker& dr)
{
os << "|" << dr.m_ticker << "|";
return os;
}
int main() {
std::vector<Ticker> table = std::move(std::vector<Ticker>{std::move(Ticker("MSFT")), std::move(Ticker("TSL"))});
for (const auto& row: table)
{
std::cout << row << std::endl;
}
return 0;
}
這會產生以下 output:
Parametrized constructor
Move constructor
Parametrized constructor
Move constructor
Copy constructor
Copy constructor
Destructor
Destructor
Destructor
Destructor
|MSFT|
|TSL|
Destructor
Destructor
有沒有辦法避免復制構造函數並就地初始化或只是移動而不復制?
如果你使用
std::vector<Ticker> table = std::vector<Ticker>{Ticker("MSFT"), Ticker("TSL")};
你會得到
Parametrized constructor
Parametrized constructor
Copy constructor
Copy constructor
Destructor
Destructor
|MSFT|
|TSL|
Destructor
Destructor
其中有 4 個構造函數調用,而不是您當前擁有的 6 個。 其中 2 個調用是針對Ticker("MSFT")
和Ticker("TSL")
的,另外兩個副本是因為初始化列表將其中的元素存儲為const
,因此必須盡可能將它們復制到向量中' t 從const
object 移動。
要獲得最少的 2 次構造函數調用,您需要使用emplace_back
成員 function,例如
std::vector<Ticker> table; // create empty vector
table.reserve(2); // allocate space for 2 Tickers but create nothing
table.emplace_back("MSFT"); // directly construct from "MSFT" in the reserved space
table.emplace_back("TSL"); // directly construct from "TSL" in the reserved space
其中有 output
Parametrized constructor
Parametrized constructor
|MSFT|
|TSL|
Destructor
Destructor
如果你想要像std::vector<Ticker> table = std::vector<Ticker>{Ticker("MSFT"), Ticker("TSL")};
這樣的語法 ,但沒有額外的開銷,您可以將emplace_back
解決方案包裝在工廠 function 中,例如
template <typename T, typename... Args>
auto make_vector(Args&&... args)
{
std::vector<T> data;
data.reserve(sizeof...(Args));
(data.emplace_back(std::forward<Args>(args)), ...);
return data;
}
然后你會像這樣使用它
auto table = make_vector<Ticker>("MSFT", "TSL");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.