C++中矢量到矢量复制是如何工作的?

huangapple go评论68阅读模式
英文:

How does vector to vector copy work in c++?

问题

在这里,当我们进行向量到向量的复制时,期望会发生什么?它会调用一个单一的memcpy,还是会隐式调用vec_b.size()次memcpy?

英文:

I have the following vector-to-vector copy.

vec_a = vec_b;

Here, vec_a and vec_b holds vec_structurename elements.

Structure definition is something like this.

typedef struct{
    uint16 name;
    other_strctuname info;
}vec_structurename;

My question is when we do vector-to-vector copy here. What's the expectation?. Will it call a single memcpy or will it call vec_b.size() number of memcpy implicitly?

答案1

得分: 1

更贴近一点的写法是这样的。或者更恰当地说,你应该这样考虑:

// vec_a = vec_b
//
vec_a.clear();
vec_a.reserve(vec_b.size());  // 或者 vec_a.reserve(vec_b.capacity()) 
for (size_t i = 0; i < vec_b.size(); i++) {
    vec_a.push_back(vec_b[i]);
}

然而,编译器可以自由地优化对于普通值类型和可平凡复制的结构体的向量复制,先为 vec_a 进行内存分配,然后进行类似 memcpy 的复制。

否则,当每个 push_back 调用都在调用每个复制构造函数时:

vec_a[i] = vec_structurename(vec_b[i]);

没有显式复制构造函数时,将是逐成员赋值:

vec_a[i].name = vec_b[i].name;
vec_a[i].other_strctuname = vec_b[i].other_strctuname;

对于 other_strctuname 的赋值也是一样的。它要么利用该类的复制构造函数,要么回退到逐成员赋值。

再次强调,如果一切都是可平凡复制的,编译器可以自由地进行快速分配和 memcpy

英文:

It's closer to this. Or more appropriately, this is how you should think about it:

// vec_a = vec_b
//
vec_a.clear();
vec_a.reserve(vec_b.size());  // OR vec_a.reserve(vec_b.capacity()) 
for (size_t i = 0; i &lt; vec_b.size(); i++) {
    vec_b.push_back(vec_b[i]);
}

However, the compiler is free to optimize a vector copy with a memory allocation for vec_a followed by a memcpy like copy for plain-old-value types and trivially copyable structs.

Otherwise, when each push_back call is invoking the copy constructor of each

vec_a[i] = vec_structurename(vec_b[i]);

Without an explicitly copy constructor, it will be a member by member assignment:

Which in the case of your data structure, is mostly this:

vec_a[i].name = vec_b[i].name;
vec_a[i].other_strctuname  = vec_b[i].other_strctuname;

Same goes for the assignment of other_strctuname. It will either make use of the copy constructor of that class or fallback to member by member assignment.

Again, if everything is trivially copyable, the compiler is free to do a quick allocation and memcpy.

Here's a Godbolt example using your class as an example with different types. For the trivially copyable classes, you can see the new + memcpy getting invoked within the inline assembly. For the struct that has a string, it has to do something else.

https://www.godbolt.org/z/o973PeGx1

答案2

得分: -1

只需调用一次memcpy,因为源元素存储在连续的内存块中,只需简单复制。

英文:

just call a single memcpy,because the source is the elements are stored in a continuous block of memory,just easy copy.

huangapple
  • 本文由 发表于 2023年2月16日 17:52:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定