std::vector 是否隐式"move"?



考虑以下代码:

#include <iostream>
#include<vector>
#include<unordered_map>
class Domain {
public:    
enum class fieldname {
pos_x, pos_y
};
std::unordered_map<fieldname, std::vector<double>> data;
};
int main()
{
Domain d;
std::vector<double> f = {1, 3, 4, 5};
d.data[Domain::fieldname::pos_x] = f;  
// if f is large? 
// d.data[Domain::fieldname::pos_x] = std::move(f);   
// use d for other stuff 
// ...
return 0;
}

使用副本将f赋值给map成员。我想知道如果使用std::像下面的注释行一样移动,它在a)内存使用b)运行时f是一个大向量(比如10% RAM)方面会有所不同。谢谢你。

首先,让我们解决"隐式move"的事情。

在此例中,f为左值。它不能绑定到右值引用。这意味着std::vector类型不能使用move构造函数,而将返回到复制构造函数。

另一方面,这段代码将移动:
int main()
{
Domain d;
d.data[Domain::fieldname::pos_x] = std::vector<double>{1, 3, 4, 5};  
return 0;
}

在这种情况下,实体std::vector<double>{1, 3, 4, 5}是一个右值,将从。

如果向量非常大并且不能分配新的内存,您将得到一个std::bad_alloc异常,而不是移动。


现在为资源使用差异。

复制vector时,将向内存分配器请求第二次内存分配。

至于速度,通常我们可以假设内存分配和复制较慢,但您不能真正确定,因为总是存在未考虑到的特殊情况和细节。如果需要性能,则必须度量代码,并对其进行优化以满足性能需求。如果没有测量,您的更改可能会在您不知情的情况下使它变慢。

最新更新