为什么下面的代码可以编译通过?
#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;
}
Run Code Online (Sandbox Code Playgroud)
std::move的文档说
在此操作之后,移出范围中的元素仍将包含适当类型的有效值,但不一定与移动之前的值相同。
所以这实际上可以改变对象 foo2,即使它被声明为 const。为什么这有效?
我想知道为什么这个程序不能编译(msvc,gcc和clang上的相同行为):
#include <iostream>
using namespace std;
struct Action
{
virtual void action()
{
cout << "Action::action()\n";
}
};
struct ActionDecorator : Action
{
ActionDecorator(const ActionDecorator&) = delete;
ActionDecorator(Action & action) : origAction(action)
{
}
void action() override
{
decoration();
origAction.action();
}
private:
void decoration()
{
cout << "ActionDecorator::decoration()\n";
}
Action & origAction;
};
int main()
{
Action action;
ActionDecorator actionDecorator(action);
ActionDecorator actionDecorator2(actionDecorator);
actionDecorator2.action();
}
Run Code Online (Sandbox Code Playgroud)
根据我的期望,删除的拷贝构造函数应该让其他ActionDecorator实例构造ActionDecorator,因为它是Action的多态类型.相反,我必须显式地将ActionDecorator实例转换为Action并且因为编译器抱怨尝试引用已删除的复制构造函数.是否有一些解释这种行为的标准规则?