在阅读了@Mehrdad 最近的问题之后,哪些类应该是不可移动的,因此是不可复制的,我开始想知道是否存在可以复制但不能移动的类的用例.从技术上讲,这是可能的:
struct S
{
S() { }
S(S const& s) { }
S(S&&) = delete;
};
S foo()
{
S s1;
S s2(s1); // OK (copyable)
return s1; // ERROR! (non-movable)
}
Run Code Online (Sandbox Code Playgroud)
虽然S有一个复制构造函数,但它显然不会对CopyConstructible概念进行建模,因为这反过来又是MoveConstructible概念的改进,需要存在(未删除的)移动构造函数(参见§17.6.3.1/2,表21) .
是否有类似S上述类型的用例,可复制但不可 CopyConstructible 移动?如果没有,为什么不禁止在同一个类中声明复制构造函数和已删除的移动构造函数?
我已经阅读了几个答案和许多有关移动语义的文章,因此它只是对右值引用的静态转换,这个问题是关于它对堆栈的影响,那么移动后堆栈是否会留下碎片?还是以某种方式重新排列?因为堆栈移动的对象不受堆栈展开的影响。以下代码片段运行良好:
#include <memory>
#include <cassert>
struct A {
int x = 0;
};
struct B {
A a;
};
void SetB(B& b) {
A a1{6}; //pushing into the stack.
A a2{7}; //pushing into the stack.
b.a = std::move(a2);
}
int main()
{
B b;
SetB(b);
assert( b.a.x == 7);
}
Run Code Online (Sandbox Code Playgroud)
a2是在SetB堆栈帧中定义的,但在SetB完成并且控件返回到后仍然可用main。然而; a1不是尽管它更接近main堆栈帧吗?