【发布时间】:2021-11-06 22:11:55
【问题描述】:
我正在尝试了解 std::move。在我的代码中,我从std::list<struct Data> 移动一个元素,其中struct Data 内部包含两个std::string 字段,但我没有得到预期的输出。这是我的代码:
#include <iostream>
#include <string>
#include <list>
struct Data {
std::string topic {};
std::string msg {};
Data(const std::string& topic, const std::string& msg) {
this->topic = topic;
this->msg = msg;
}
};
int main() {
std::list<Data> data_list;
data_list.push_back(Data("A", std::string(1000, 'a')));
data_list.push_back(Data("B", std::string(1000, 'b')));
data_list.push_back(Data("C", std::string(1000, 'c')));
data_list.push_back(Data("D", std::string(1000, 'd')));
data_list.push_back(Data("E", std::string(1000, 'e')));
while (!data_list.empty()) {
std::cout << (void*)&data_list.front() << "\n";
Data&& d1 = std::move(data_list.front());
data_list.pop_front();
std::cout << d1.topic << ", " << d1.msg << "\n";
std::cout << (void*)&d1 << "\n\n";
}
std::cout << std::endl;
}
【问题讨论】:
-
您存储对第一个元素的引用,然后弹出第一个元素。你会得到一个悬空的引用和未定义的行为。
-
您无法移动此特定实例。但是,如果您像 NathanOliver 在他的好答案中所做的那样,隐式 move-ctor 会将两个字符串成员管理的内存移动到新实例(而不是复制内存)。是的,
std::move使用起来并不直观 :) -
考虑使用
emplace_back(),像这样:data_list.emplace_back("A", std::string(1000, 'a'))。