首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拥有一个按值返回的函数的最佳方法是什么?堆分配返回值?

拥有一个按值返回的函数的最佳方法是什么?堆分配返回值?
EN

Stack Overflow用户
提问于 2022-08-31 15:57:14
回答 1查看 85关注 0票数 1

假设我有一个简单的函数returnString,它按值返回一个字符串:

代码语言:javascript
复制
std::string returnString() {
   std::string s;
   // Use s in such a way to defeat return value mandatory copy-elision
   return s;
}

我还有一个要堆的函数--分配这个结果。很简单。

代码语言:javascript
复制
void caller() {
   std::string* heap_allocated_string = new std::string(returnString());
}

但是,不要考虑std::string,而是考虑任意类型的T。我相信,按照语言规则,以下两种说法是正确的。是吗?

  1. In C++14,我认为这并不理想,因为对于某些类型,如果移动ctor不是空闲的或未定义的,与直接在堆上进行构造相比,我们可能要做不必要的工作。C++17中的
  2. 会触发强制复制选择,因此即使该类型没有定义移动构造函数,也不会创建额外的副本,移动构造函数也不会被调用。

一般来说,对于泛型类型,是否有更好的方法来做到这一点,而不修改被调用的函数呢?

EN

回答 1

Stack Overflow用户

发布于 2022-08-31 16:29:55

In C++14,我认为这并不理想,因为对于某些类型,如果移动ctor不是空闲的或未定义的,我们可能要做不必要的工作,而不是直接在堆上构建。

定义“不理想”。

如果必须通过一个按值返回的工厂函数来构造对象,并且您想要堆--而不是分配对象,那么您必须“不修改被调用的函数”来完成这个任务,那么这就和它将要得到的一样好。

另外,您不必担心在C++14中缺少复制/移动。原因是在C++14中通过值返回一个不可复制、不可移动的对象(几乎)是不可能的。从技术上讲,有一种方法(通过使用return语句中的列表初始化语法),但是如果函数是按照您的说明编写的,那么它返回的任何类型都必须是可复制的或可移动的。

此外,您端的new表达式甚至不需要命名RVO;这部分只是临时的,编译器没有理由不能优化这个迁移。

因此,基本上,要编译函数必须有一个复制/移动构造函数,并且为了所有实际目的,任何复制/移动都将在您的末端进行优化。所以没什么好担心的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73558705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档