有没有办法在初始化向量时避免复制?
下面的代码将产生以下输出。
#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;
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
Parametrized constructor
Move constructor
Parametrized constructor
Move constructor
Copy constructor
Copy constructor
Destructor
Destructor
Destructor
Destructor
|MSFT|
|TSL|
Destructor
Destructor
Run Code Online (Sandbox Code Playgroud)
有没有办法避免复制构造函数并就地初始化或只是移动而不复制?
Nat*_*ica 13
如果你使用
std::vector<Ticker> table = std::vector<Ticker>{Ticker("MSFT"), Ticker("TSL")};
Run Code Online (Sandbox Code Playgroud)
你会得到
Parametrized constructor
Parametrized constructor
Copy constructor
Copy constructor
Destructor
Destructor
|MSFT|
|TSL|
Destructor
Destructor
Run Code Online (Sandbox Code Playgroud)
其中有 4 个构造函数调用,而不是当前的 6 个。其中 2 个调用是 forTicker("MSFT")和Ticker("TSL"),然后另外两个副本是因为初始值设定项列表将其中的元素存储为const,因此必须将它们复制到向量中,因为您无法从对象移动const。
要获得最少 2 个构造函数调用,您需要使用emplace_back成员函数,例如
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
Run Code Online (Sandbox Code Playgroud)
其输出为
Parametrized constructor
Parametrized constructor
|MSFT|
|TSL|
Destructor
Destructor
Run Code Online (Sandbox Code Playgroud)
如果您想要类似的语法std::vector<Ticker> table = std::vector<Ticker>{Ticker("MSFT"), Ticker("TSL")};,但又没有额外的开销,您可以将emplace_back解决方案包装在工厂函数中,例如
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;
}
Run Code Online (Sandbox Code Playgroud)
然后你会像这样使用它
auto table = make_vector<Ticker>("MSFT", "TSL");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
637 次 |
| 最近记录: |