Dav*_*nan 1 c++ copy stdvector
假设我有一个向量:
std::vector<uint64_t> foo;
foo.push_back(1);
foo.push_back(27);
Run Code Online (Sandbox Code Playgroud)
我通过引用将该向量传递给函数。
calculate_something(foo);
int calculate_something(std::vector<uint64_t>& vec) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
在极少数情况下,函数需要本地修改向量,在这种情况下必须创建副本。这是正确的方法吗?
if (some_condition) {
vec = vec;
}
vec.push_back(7);
Run Code Online (Sandbox Code Playgroud)
编辑:我自我分配的原因是因为分配给另一个变量会产生一个副本,我的直觉告诉我,当分配回同一个变量时,也会发生同样的情况。
use*_*522 10
不,这是不正确的。
C++ 中的赋值不会创建新对象或更改引用引用的对象。赋值仅更改左侧引用的对象的值(通过内置赋值运算符或通过operator=重载的常规行为)。
为了创建比表达式求值持续时间更长的新对象,您需要声明某个变量。这样的声明可以有一个初始化器,使用=它经常与赋值混淆,但事实并非如此:
std::vector<uint64_t> vec2 = vec;
Run Code Online (Sandbox Code Playgroud)
这将创建一个新vec2类型的对象std::vector<uint64_t>并使用 对其进行初始化vec,这意味着将vec其状态复制到vec2。这不是作业!如果你写的是
vec2 = vec;
Run Code Online (Sandbox Code Playgroud)
那么您可以进行赋值操作,将名为 的对象的状态修改vec2为等于 引用的对象的状态vec。但为了做到这一点,必须已经有一个声明,vec2其中已创建向量对象本身。分配不是创建一个新对象。
如果你只是使用
vec = vec;
Run Code Online (Sandbox Code Playgroud)
那么只有一个对象,即所vec引用的对象。是否允许这种赋值并不明显,但即使在最好的情况下,它所能做的就是将引用的对象的状态复制vec到引用的对象中vec,这意味着最后的状态vec应该简单地保持不变,并且没有其他副作用。
一般来说,您不能将 C++ 中的名称或引用重新绑定到新对象。
所以你想要的是
std::vector<uint64_t> local_vec = vec;
Run Code Online (Sandbox Code Playgroud)
然后您可以将local_vec其用作 的本地副本vec。auto您可以通过使用来指示您希望变量具有与右侧相同的类型(减去引用和const限定符),从而避免指定类型:
auto local_vec = vec;
Run Code Online (Sandbox Code Playgroud)