下面的代码将包含大 vector 的对象传递到 vector 中。我希望它表现出色。我是否需要在对test
的调用中将push_back
强制转换为rvalue?我需要告诉编译器如何 move struct Test
实例吗?还是全部自动进行?
int main()
{
struct Test
{
std::vector<size_t> vals;
double sum;
};
std::vector<Test> vecOfTest;
vecOfTest.reserve(100000);
for (size_t i = 0; i < 100000; i++)
{
Test test{};
test.vals.reserve(i);
for (size_t j = 0; j < i; j++)
{
test.vals.push_back(j);
test.sum += j;
}
vecOfTest.push_back(test);
}
return 0;
}
最佳答案
您的Test
结构没有定义任何特殊的成员函数(复制构造函数,析构函数等),这意味着会自动生成一个默认的 move 赋值运算符和一个默认的 move 拷贝构造函数,它们将 move 该结构的每个数据成员。因此Test
是可 move 的类型,并且由于vector<size_t>
是可 move 的数据成员而从中受益。
但是,不会自动执行 move ,因为从对象 move 会更改它。即使您认为这是:
vecOfTest.push_back(test);
}
将执行隐式 move ,因为范围结束了,但不会结束。隐含的举动将使编译器和程序员都陷入困境。要求编译器证明使
test
无效是可以的。程序员将被要求不断研究是否需要显式 move ,而其最终结果将是无论如何都只是进行显式 move 。因此,由于这个原因,不会发生隐式 move (但请参阅下面的规则异常(exception)。)您需要自己执行此操作:vecOfTest.push_back(std::move(test));
唯一不需要 move 的情况是 move 会干扰省略。例如,在返回
Test
的函数中,这是:Test test;
return std::move(test);
会 move ,但最好不要 move 。最好:
return test;
反而。这不是一个隐含的举动。这是一个省略。清除比 move 快,而 move 将阻止清除。但是,在无法进行省略的情况下,将执行隐式 move 。这是我唯一知道发生隐式 move 的位置的情况:作为省略的替代方法。您的原始代码:
vecOfTest.push_back(test);
不是为了省事,所以永远不会发生隐性举动。
关于c++ - 在向 vector 添加自定义对象时如何启用 move 语义?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55965412/