【发布时间】:2022-01-14 12:14:52
【问题描述】:
为什么下面的代码会编译?
#include <vector>
#include <iostream>
struct Foo {
std::vector<int> bar = {1, 2, 3};
};
int main()
{
Foo foo1;
const Foo& foo2 = foo1;
std::vector<int> target;
std::move(foo2.bar.begin(), foo2.bar.end(), std::back_inserter(target));
return 0;
}
std::move 的文档说
此操作后,移动范围内的元素仍将 包含适当类型的有效值,但不一定是 与移动前相同的值。
所以这实际上可以改变对象 foo2,即使它被声明为 const。为什么会这样?
【问题讨论】:
-
您正在为 Foo 结构分配内存,然后将其标记为
const,因此您正在阻止更改该变量的引用。由于vector<>指向另一块内存,您可以自行调整它。如果您想阻止该向量进行更改,请将其标记为 const:const vector<int> nums {1, 2, 3} -
@yemo 不确定这是否解释了整个故事。我可以简化示例代码further。即使
bar是const std::vector<int>,std::move也是允许的。 -
“不一定”是一个笼统的说法,但可能不适用于特定的场景。例如,“您收到的亲笔签名的物品可能不一定与展示的物品相同。”但是你说“啊哈,但在我的情况下,我知道该项目是独一无二的,唯一存在的项目是展示项目。'不一定'意味着商店有权力复活,可以让名人起死回生,让他们再签一件,然后卖给我吗?”
-
@nemo,您不应该使用对容器的 const 引用来改变容器元素(除非使用
mutable)。类似地,作为 const 的结构将该属性传输到其内容。所以确实,这个问题在我看来是非常有道理的!
标签: c++ language-lawyer move-semantics