什么是复制省略和返回值优化?

什么是复制省略?什么是(命名)返回值优化?它们意味着什么

在什么情况下会发生这种情况?限制是什么

  • 如果你被提到这个问题,你可能正在寻找介绍
  • 有关技术概述,请参阅标准参考资料
  • 请参见此处的常见案例

导言

有关技术概述,请跳到此答案

对于发生复制省略的常见情况,请跳到此答案

拷贝省略是大多数编译器实现的一种优化,用于在某些情况下防止额外的(可能昂贵的)拷贝。它使按值返回或按值传递在实践中可行(适用限制)

这是唯一一种省略的优化形式(哈!)即使复制/移动对象有副作用,也可以应用“仿佛”规则-复制省略

以下示例摘自维基百科:

预结构{
C(){}
C(const C){std::cout<<<<<<<<<<<<<<<<<<<<<>>>&gt
};
C f(){
返回C();
}
int main(){
std::cout“你好,世界!\n”;;
C obj=f();
}

取决于编译器&设置,以下输出均有效

你好,世界
复制了一份
复制了一份


你好,世界
复制了一份


你好,世界

这也意味着可以创建更少的对象,因此您也不能依赖于调用特定数量的析构函数。复制/移动构造函数或析构函数中不应该有关键逻辑,因为不能依赖于调用它们

如果省略了对复制或移动构造函数的调用,则该构造函数必须仍然存在并且可以访问。这确保复制省略不允许复制通常不可复制的对象,例如,因为它们具有私有或已删除的复制/移动构造函数

C++17:从C++17开始,当直接返回对象时,可以保证省略复制:

结构C{
C(){}
C(const C){std::cout<<<<<<<<<<<<<<<<<<<<<>>>&gt
};
C f(){
return C();//绝对执行复制省略
}
C g(){
C C;
返回c;//可能执行复制省略
}
int main(){
std::cout“你好,世界!\n”;;
C obj=f();//未调用复制构造函数
}

发表评论