std::vector 是否可以简单复制,为什么?
Is std::vector trivially copyable and why?
我遇到了 std::vector<T>
的问题,其中 T
是一个内置类型,表示向量不可简单复制。
不知是否正确,正在寻找原因
形式上,std::vector<T>
(对于任何 T
)不是 trivially copyable because its copy constructor is not trivial,只是因为它是用户提供的(而不是隐式定义的)。
实际上,复制向量不仅仅是对其数据成员进行浅表复制 - 它需要在堆上分配内存缓冲区并从另一个向量的堆分配缓冲区复制其内容。
A vector
随着数据的添加而增长。这意味着不需要预先知道需要多少 space 来存储所有数据。 vector
通过在堆上分配(和重新分配)一个单独的存储缓冲区来解决这个问题。该缓冲区在内部进行管理,同时提供一个可以看作可变大小数组的接口。
现在,如果一个对象是简单可构造的,那么只需使用 memcpy(dest, &a, sizeof(a))
就应该能够 copy/clone 该对象。如果要为 vector
执行此操作,则会有 2 个向量对象指向同一存储缓冲区。这将导致可怕的未定义行为。因此,复制向量需要复制内部存储,复制其参数,然后将内部指针设置为指向正确的存储缓冲区。这需要对象的内部知识来做。
std::array
但是,在编译时设置了静态大小。它没有内部指针,因此可以简单地使用 memcpy
进行复制。因此复制起来很简单。
我遇到了 std::vector<T>
的问题,其中 T
是一个内置类型,表示向量不可简单复制。
不知是否正确,正在寻找原因
形式上,std::vector<T>
(对于任何 T
)不是 trivially copyable because its copy constructor is not trivial,只是因为它是用户提供的(而不是隐式定义的)。
实际上,复制向量不仅仅是对其数据成员进行浅表复制 - 它需要在堆上分配内存缓冲区并从另一个向量的堆分配缓冲区复制其内容。
A vector
随着数据的添加而增长。这意味着不需要预先知道需要多少 space 来存储所有数据。 vector
通过在堆上分配(和重新分配)一个单独的存储缓冲区来解决这个问题。该缓冲区在内部进行管理,同时提供一个可以看作可变大小数组的接口。
现在,如果一个对象是简单可构造的,那么只需使用 memcpy(dest, &a, sizeof(a))
就应该能够 copy/clone 该对象。如果要为 vector
执行此操作,则会有 2 个向量对象指向同一存储缓冲区。这将导致可怕的未定义行为。因此,复制向量需要复制内部存储,复制其参数,然后将内部指针设置为指向正确的存储缓冲区。这需要对象的内部知识来做。
std::array
但是,在编译时设置了静态大小。它没有内部指针,因此可以简单地使用 memcpy
进行复制。因此复制起来很简单。