问题标签 [copy-elision]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
596 浏览

c++ - 具有复制省略或移动语义的 C++11 元组

我写了一个如下函数:

由于返回类型非常复杂,是否保证在 c++11 下编译器在构造结果时将应用复制省略或移动语义,或者我必须明确地说 std::move(std::make_tuple( std::move(p), 10, 10))?

0 投票
1 回答
329 浏览

c++ - 在执行复制省略时,当删除移动构造函数时,编译器不会在重载决议中考虑复制构造函数。为什么?

我可以理解编译器在下面的代码中进行了复制省略,因为在所谓的copy-initializationdone in中没有调用复制和移动构造函数main()。见活的例子

但我不明白为什么当我删除移动构造函数时代码无法编译,如下所示:

在这种情况下,我在 §12.8/32 (N4140) 中找不到任何可能禁止使用或省略复制构造函数的内容。这是第 12.8/32 节中引起我注意的一句话,这似乎表明应该在重载决议中考虑复制构造函数:

如果第一个重载决议失败或未执行,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是 cv 限定的),则再次执行重载决议,将对象视为左值。

编辑

从下面TC的评论之一,我了解到,当要复制的对象由右值指定时,根据 §12.8/32,编译器不会将复制构造函数视为复制的候选者,甚至尽管无论如何都会忽略副本。也就是说,最终结果将是s使用默认构造函数构造对象。相反,在这种情况下,标准要求(在哪里??)代码格式错误。除非我对这个方案的理解完全错误,否则这对我来说没有任何意义。

0 投票
1 回答
511 浏览

c++ - 隐式类类型转换是否使用复制构造函数?

我的 C++ 书中的以下引用:

当我们使用直接初始化时,我们要求编译器使用普通函数匹配来选择与我们提供的参数最匹配的构造函数。当我们使用复制初始化时,我们要求编译器将右手操作数复制到正在创建的对象中,并在必要时转换该操作数。

对我来说,这个粗体字会产生一些歧义。例如,这听起来像是将右侧的操作数转换为类类型,然后使用了复制构造函数;

会成为...

它使用复制构造函数。如果这是真的,那么我的测试程序;

应该产生“第二种方式,第二种方式,第一种方式”。然而,它改为打印“第二种方式,第二种方式”。由此我会得出结论,它使用的是 const char* 构造函数而不是复制构造函数。我会很好的,除非后来它说...

在复制初始化期间,允许(但不是必须)编译器跳过复制/移动构造函数并直接创建对象。即允许编译器重写

进入

然而,即使编译器省略了对复制/移动构造函数的调用,复制/移动构造函数也必须存在并且必须在程序中的那个点是可访问的(例如,不是私有的)。

我不确定为什么复制构造函数甚至需要在这些示例中提及,不是

总是隐含地意味着无论如何都在使用 const char* 构造函数?实际上,需要定义复制构造函数才能使上述内容起作用,这对我来说意义不大。但是,如果我将“const A&”构造函数设为私有(其余为公共),那么我的程序将无法运行。为什么必须为甚至不涉及它的隐式转换定义复制构造函数?"string null_book = "9-999-99999-9"" 使用什么构造函数?

0 投票
1 回答
270 浏览

c++ - 下面显示的代码段中没有省略移动构造函数是否有任何特殊原因?

gcc, clang 和 VS2015 在抛出 object 之后,不会在下面的代码中省略对 move 构造函数的调用a。在我看来,§8.12[class.copy]/31 (N4140) 的要点 (31.2) 中建立的条件得到满足。

请注意,这a是一个左值,但根据第 12.8/32 节,首先执行为复制选择构造函数的重载决策,就好像对象是由右值指定的一样。也就是说,调用移动构造函数是可以的。如果您删除上面移动构造函数的定义,则会调用复制构造函数,但同样,它不会被忽略!

我知道标准没有强制要求复制省略,但我很想知道是否有任何特殊条件可以证明上述三个编译器在这个特定示例中避免了这种优化这一事实。

gcc 的示例输出,来自上面的链接:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

默认 ctor

移动 ctor

析构函数

抓住

析构函数

0 投票
5 回答
429 浏览

c++ - 无论复制省略如何,此代码是否定义明确?

考虑这段代码:

人们会期望这样的输出:

这确实是我得到的。但是由于复制省略,可能out与内存中的最后一行输出位于同一位置in并导致输出为x: 2, y: 2?

我试过用 gcc 和 clang 编译-O0and -O3,结果仍然看起来像预期的那样。

0 投票
2 回答
77 浏览

c++ - 为什么对象副本构造和销毁两次?

为什么在下面的代码中会出现一对“额外的”复制构造函数和破坏?

当叮咚的构造函数将 STL 容器作为参数时会发生这种情况(我尝试过 std::vector 和 std::list)。它可能发生在其他事情上吗?如果构造函数取而代之的是指针,则不会发生。如果我在堆上分配 ding 也不会发生( Dingledong* ding = new Dingledong(v) )。

输出:

先感谢您!

0 投票
2 回答
221 浏览

c++ - 为什么复制省略对形式参数有例外?

这是一个完整的程序:

有趣的是复制构造函数有一个副作用,并且有两个版本operator+需要考虑。

情况1

案例2

Visual Studio 2015 给出了相同的结果,打印结果为1. 但是 gcc 4.8.4 给出2了案例 1。

这个复制省略的总结※</sup> 声明“<em>这不是函数参数”,这让我认为 VS 是错误的。那是对的吗?

但是,为什么在这条规则中要特别对待形式参数名称呢?为什么它不完全像任何其他局部变量?

(我并不是说优化器根据调用约定并根据调用者和被调用者的单独编译来解决问题,而只是说为什么不允许这样做。)

编辑:如果输出1是正确的,这与省略规则有何关系?


注意※:我发现这段文字是从公开的N3690中的 §12.8 第 31 段复制而来的。

0 投票
0 回答
39 浏览

c++ - 如何对复制省略/返回值优化充满信心

我经常按值返回对象,假设会发生复制省略/RVO。

但是我对编译器没有很好的底层理解,有时我的代码中的某些内容可能会在我不知情的情况下破坏复制省略,这让我感到害怕。

是否有一套简单的规则需要牢记,在这些规则下我可以有理由相信会发生复制省略(或者至少,我没有阻止它)?

0 投票
4 回答
5121 浏览

c++ - 按值传递参数的复制省略

给定

假设我们运行Box box(Range(0.0,1.0),Range(0.0,2.0)).

Range启用优化的现代编译器能否在此构造过程中完全避免复制对象?(即构造Range里面的对象box开始?)

0 投票
2 回答
271 浏览

c++ - 任何编译器实际上会忽略这些副本吗?

给定

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

任何编译器实际上都这样做吗?

我自己的尝试没有成功。