【问题标题】:copy elision in c++03c++03中的复制省略
【发布时间】:2021-03-01 12:57:02
【问题描述】:

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

【问题讨论】:

    标签: c++ language-lawyer c++03 copy-elision


    【解决方案1】:

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

    复制操作的非强制性省略

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

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

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

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

    cppreference

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2010-12-14
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多