避免在移动构造函数中实现数据移动之外的功能
8.19 ID_sideEffectMoveConstructor
移动构造函数的执行在某些情况下可被省略,其执行次数可能与预期不符,数据移动之外的功能也可能无法生效。
示例:
class A {
int* dat;
static int cnt;
public:
A();
~A();
A(A&& a) {
dat = a.dat; // Compliant
a.dat = nullptr; // Compliant
cnt++; // Non-compliant
}
};
例中移动构造函数对静态成员有所读写,这种数据移动之外的功能是不符合要求的。
如果按下列方式使用相关类:
A foo();
int main() {
A a{foo()}; // Copy/move elision
....
}
用相同类型的临时对象构造对象 a,标准允许编译器将临时对象直接当作对象 a,移动和拷贝构造函数均可省略以提高效率,这种优化称为“copy/move elision”,移动或复制之外的功能会因此无法生效。在 C++17 之前,是否执行这种优化由实现定义,C++17 规定在某些情况下必须执行这种优化,具体可参见“guaranteed copy elision”。
相关
依据
ISO/IEC 14882:2011 12.8(31)-implementation
ISO/IEC 14882:2017 15.8.3(1)-implementation