问题标签 [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.
c++ - 保证省略和链式函数调用
假设我有以下类型:
我有声明(假设所有命名变量都是左值类型X
):
在 C++17 中,我对这个表达式将执行多少个副本和移动有什么保证?非保证省略怎么办?
c++ - 如何就地初始化数组?
如何在不复制或移动构造临时元素的情况下初始化数组?当元素具有显式delete
d 复制或移动构造函数时,只有当元素具有默认 ctor 或具有所有默认参数的 ctor 并且我执行以下操作之一时,我才能初始化数组:(a)明确声明数组,(b ) 直接初始化和零初始化数组,或 (c) 复制初始化和零初始化数组。直接(但不是零)初始化和复制(但不是零)初始化都不会编译。
- 这 3 种方法是在不复制/移动临时元素的情况下初始化数组的唯一方法吗?
a1
将,a2
和a3
count 作为初始化吗?ega1
是一个声明,但它的元素获取初始值,尽管是默认值。- 他们中的任何一个都是错误吗?我用 C++14 标志做了这个 GCC 6.3.0。
- 为什么复制初始化结合零初始化仍然在复制初始化的范畴下工作?
- 一般来说,所有带有花括号的数组初始化都只是临时元素的构造(除非在没有删除复制或移动构造函数时省略(或者省略不适用于数组?)),然后是每个元素的复制、移动或混合复制和移动构造?
c++ - C++11 复制 elison 和异常(catch 参数)
经过代码审查后,我们在 try/catch 块中遇到了复制 elison 的问题。阅读本页后: cpp 参考指南,尤其是本段:
处理异常时,如果 catch 子句的参数与抛出的异常对象属于同一类型(忽略顶级 cv 限定),则省略副本,并且 catch 子句的主体直接访问异常对象,如如果被引用捕获
我认为 catch 中参数的复制省略会自动执行,但是其中一位审阅者运行了一个简单的测试,表明编译器没有执行复制省略:
编译时:
我得到以下输出
我期待一个类似于(抛出异常时只调用一次复制构造函数)的输出:
测试已在 Linux Ubuntu 16.04 下运行 g++ 版本:
是测试用例无效还是我对复制省略的理解有误?非常感谢您的帮助
c++ - 左值和右值返回类型以提高效率
更新:
- 因此,根据 Jean 的评论,我查看了此链接。这实际上非常接近我要问的问题。唯一的区别是它明确地处理类(这
cv::UMat
无疑是);但是,我尝试对返回类型进行的功能嵌套是否仍然有效?是否仍会出现复制省略,并达到预期的结果?
问题
我目前正在使用 OpenCV 的cv::UMat
对象类,我的同事编写了一个函数来进行cv::UMat
添加,如下所示:
现在,如果我这样称呼它,这很好用:
但是,当我尝试将函数作为参数传递给函数时,出现“参数必须是左值”类型错误。例如,
对于任何有效cv::UMats
的 , alpha, beta
。
至今
我做了一些研究,发现它std::move(input)
显式地返回了一个右值类型的临时值。因此,抛出错误是有道理的。
我意识到我可以通过首先执行以下操作来解决此问题:
或者,我什至可以做类似的事情,
在这种情况下,我的理解是该行将return returnMat
导致一个 deep(?) 临时被复制。
问题
所以,我知道这里可能会发生一些依赖于 OpenCV 的事情;就像,也许是因为 UMat 类型正在进行一些时髦的铸造等。
但是,在一般情况下,适应函数的最佳方法是
addUmats
能够将函数作为对函数的调用?
在运行时方面,我将寻求最有效的解决方案。另外,我不希望这个问题仅限于 OpenCV 案例;获得使用该std::move(input)
调用的任何类型函数的答案将不胜感激。
c++ - 为什么for_each通过移动返回函数
我正在阅读std::for_each
这里的文档http://en.cppreference.com/w/cpp/algorithm/for_each并看到返回值是std::move(f)
为什么标准强制在返回值中移动输入参数?由于输入参数是按值传递的,所以默认情况下不会移动它吗?
当您编译以下代码时,这导致我进行了一些后续操作
return 语句是在我的系统上具有最高优化级别 (
-O3
) 的移动,为什么大多数编译器不忽略这个返回值?局部值被省略,但函数参数不是..在这种情况下,C++17 是否强制省略?我阅读了该提案(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html),但我不完全了解哪些情况符合强制省略的条件。
我已经Apple LLVM version 8.0.0 (clang-800.0.42.1)
在我的 Mac 和g++ 5.4
Ubuntu 16.04 上尝试过这个。
c++ - const 引用来延长对象的生命,然后是 const_cast,这是个好主意吗?
考虑以下返回大对象的函数:
我想得到清单,而不是它的副本。因为如果我必须复制这样的对象,性能代价是昂贵的。我知道返回值优化可能会为我解决这个问题,但是依靠优化来优化坏代码并不是最好的方法(对吧?)。
避免复制和延长对象寿命的一种干净方法是使用常量引用(请在将其称为悬空引用之前对其进行测试,因为它不是):
在 C++11 中,可以std::move
用来避免复制。但是,我正在开发一个 C++03 程序,我必须这样做:
现在我需要将列表拼接在一起。我这样做的唯一方法是复制所有内容,或者const_cast
这些列表并将它们拼接起来。有更好的解决方案吗?
c++ - 返回复制的对象
在如下函数中:
编译器可以轻松执行 RVO,因此请执行以下操作:
但是,我已经看到第二种方式有时比前者更可取,例如在 STL 算法实现 (gcc) 中,我想知道这是否会以任何方式(如std::move(*it)
或std::move(tmp)
确实)影响 RVO,或者有任何其他原因,因为例如,关于转换或其他任何事情。
例如reserver_iterator
,,而不是:
用途:
我之所以这么问,是因为为了实现类似 的重载operator+
,我广泛使用了以下模式:
代替:
这并不是特别具有可读性,但使它长了 3 行(一行中的这两个句子会很丑)。
c++ - 如何强制调用移动构造函数,我为什么要这样做?
我测试了这段代码,看看编译器会自动将临时对象传输到变量,而不需要移动构造函数。
此代码打印“Hi from default from getA”,而不是假定的“Hi from move”
在优化方面,它很棒。但是,如何在不添加副本的情况下强制调用移动构造函数?(如果我想要临时对象的特定行为)
补充问题:我认为,如果我没有编写移动构造函数,那么每次我将右值分配给左值时都会有一个副本(就像在该行的代码中一样A b(getA());
)。既然情况并非如此,而且编译器似乎做得很好,那么实现移动语义什么时候真正有用?
c++ - 返回对象的函数未执行深度复制。为什么 foo() 返回的 temp 没有被深度复制?
** foo() 返回的临时对象不会被复制。在 this 中调用普通构造函数,但不调用复制构造函数。谁能指出我到底哪里出错了。**
c++ - 保证复制省略是否适用于函数参数?
如果我理解正确,从 C++17 开始,这段代码现在要求不进行任何复制:
函数参数也是如此吗?副本会在以下代码中被优化掉吗?