任何编译器是否真的会忽略这些副本?

Mus*_*ful 6 c++ pass-by-value copy-elision

特定

struct Range{
    Range(double from, double to) : from(from), to(to) {}
    double from;
    double to;
    // if it matters to the compiler, we can add more fields here to make copying expensive
};

struct Box{
    Box(Range x, Range y) : x(x), y(y) {}
    Range x;
    Range y;
};
Run Code Online (Sandbox Code Playgroud)

有人说,Box box(Range(0.0,1.0),Range(0.0,2.0))编译器可以Range通过在内部构建它们box来完全避免复制对象.

有没有编译器真的这样做?

我自己的尝试没有成功.

Die*_*ühl 8

编译器可以 - 通常是 - 将副本从临时副本中删除到参数.编译器不能将参数的副本从成员中删除.虽然在某些情况下技术上可能会遗漏这些副本,但未给出相关许可.标准的部分是12.8 [class.copy]第31段,其中列出了可以省略副本的4种情况(确切的规则有点不重要):

  1. 使用名称返回命名的函数局部变量时.
  2. throw表达式中使用named,function局部变量时.
  3. 复制临时对象时.
  4. 按值捕获异常时.

将命名参数作为参数传递给成员变量的构造显然不是这些情况.

复制省略规则的基本背景是,在某些情况下,函数声明足以确定何时使用对象.如果在施工时间清楚可以构造物体,则可以省略.构造函数的调用者无法仅基于将使用对象的构造函数的声明来确定.