加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如果我按功能从函数返回STL容器,GCC会单独复制所有元素吗?

发布时间:2020-12-16 10:19:15 所属栏目:百科 来源:网络整理
导读:如果我有以下函数声明返回std :: list Triangle *按价值: std::listTriangle* getAllAbove(Triangle* t); 当我返回std :: list Triangle * (在getAllAbove结束时在getAllAbove的堆栈中创建),GCC能够优化对std :: list Triangle *的复制构造函数的调用(可能
如果我有以下函数声明返回std :: list< Triangle *>按价值:

std::list<Triangle*> getAllAbove(Triangle* t);

当我返回std :: list< Triangle *> (在getAllAbove结束时在getAllAbove的堆栈中创建),GCC能够优化对std :: list< Triangle *>的复制构造函数的调用(可能会迭代所有元素和复制它们,或者至少只复制列表元数据(例如不是元素本身)?该列表可能包含几千个指针,我想避免不必要地复制所有这些指针.

绕过复制构造函数调用以在堆上创建列表然后返回指向它的指针的唯一方法是什么?

解决方法

那么,绕过复制的另一种方法是使用“返回参数”习惯而不是使用函数的返回值

void getAllAbove(Triangle* t,std::list<Triangle*>& result);

不像现在那样在堆栈上形成结果,而是直接在结果参数中(即在您从调用者传递的收件人列表中)形成它.

至于原始代码,是否进行复制取决于编译器的功能.

从最抽象的角度来看,您的代码实际上有两个副本. (是的,当列表的整个内容在另一个列表中逐个元素地重复复制时,这些都是完整的复制.)首先,在函数内的堆栈上创建的命名列表对象被复制到无名的临时对象保存函数的返回值.然后将临时对象复制到调用代码中的最终收件人对象.大多数编译器将能够消除其中一个副本(以消除C98规范允许的中间临时).

为了消除第二个,编译器必须能够执行所谓的命名返回值优化(如C 03规范所允许的).支持命名返回值优化的编译器应该能够基本上隐式地将函数的接口转换为等效的上述“返回参数”惯用法.我希望GCC能够做到这一点.尝试一下,看看会发生什么.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读