在 C++03 中复制省略

问题描述

Copy-elision 在某些情况下,在 c++17 中是强制性的,在 c++11/14 中是允许的。这尤其涉及复制初始化。 比如下面的程序

#include <iostream>

struct A
{
  explicit A(int){ std::cout << "conversion" << std::endl; }
  A(const A&) { std::cout << "copy constructor" << std::endl; }
};

int main()
{
    A b = A(3);
}

预期在 c++17 中产生输出

conversion

并且在 c++11/14 中可能会产生相同的输出。在这些方面,gcc 10.1.0 和 clang 11.1.0 也使用 -std=c++11-std=c++14 生成上述输出,除非使用 -fno-elide-constructors 显式禁用可选构造函数省略。

但是c++03标准呢?是否允许在复制初始化中省略复制构造函数? gcc 和带有 -std=c++03 的 clang 总是禁止复制构造函数(除非指定了 -fno-elide-constructors)。

解决方法

是的,C++03 和 C++98 中允许复制省略。这是 C++98 和 C++03 的段落:

非强制省略复制操作

在以下情况下,编译器是允许的,但 不需要省略复制构造 类对象,即使复制构造函数和 析构函数有明显的副作用。对象被构造 直接进入存储,否则它们将被复制 到。这是一种优化:即使它发生并且 复制构造函数没有被调用,它仍然必须被调用 存在且可访问(好像根本没有发生优化), 否则程序格式错误:

  • 在 return 语句中,当操作数是具有自动存储期的非易失性对象的名称时,这不是一个 函数参数或 catch 子句参数,并且哪个是 与函数返回相同的类类型(忽略 cv 限定) 类型。这种复制省略的变体被称为 NRVO,“命名为 return 价值优化”。

  • 在一个对象的初始化中,当源对象是一个无名的临时对象并且是同一个类类型时(忽略 cv-qualification)作为目标对象。当无名临时工是 return 语句的操作数,这种复制省略的变体是 称为 RVO,“返回值优化”。

当复制省略发生时,实现将省略复制操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在两个对象将没有优化就被破坏了

cppreference

我删除了所有自 C++11 以来才有效的内容。

C++98、C++03 和 C++11 之间关于省略号的唯一区别是移动操作和异常处理。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...