c++ 11函数返回时会发生什么
C++11 what happens when a function returns
我想知道当我有一个这样的函数时会发生什么:
typedef std::unordered_map<std::string,std::string> stringmap;
stringmap merge (stringmap a,stringmap b)
{
stringmap temp(a); temp.insert(b.begin(),b.end()); return temp;
}
函数返回时会发生什么?
在被销毁(超出作用域)之前将'temp'复制到临时r值并且使用c++ 11可能进行nrvo优化(因此'temp'的副本直接写入返回目标槽)?
不应该复制任何内容。有两种可能:
-
temp
被移动到调用者作用域中的对象;或 - 移动被省略,并且
temp
成为调用者作用域中对象的别名。这被称为"返回值优化"。
在2011年之前(特别是,没有移动语义),第一种情况需要复制而不是移动。第二种情况在c++ 98和c++ 11中是允许的。
NRVO表示temp
本身是在返回值位置构造的。没有RVO,是的,temp
在被销毁之前从堆栈上的位置复制/移动到返回值位置。
在没有任何特殊规则的情况下,这通常会导致从temp
复制到函数的返回值。然而,标准中有两条规则旨在改善这一点。第一种是可以省略(12.8/31):
在具有类返回类型的函数的返回语句中,当表达式是与函数返回类型具有相同cvunqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,可以通过将自动对象直接构造为函数的返回值
来省略复制/移动操作。
这通常被称为返回值优化(NRVO),是返回值优化(RVO)的一种特殊情况。
第二个是,由于这种情况符合上述复制省略的标准,因此首先将其视为移动(12.8/32):
如果满足或将满足省略复制操作的条件(除了源对象是函数形参,且要复制的对象由左值指定),则首先执行选择复制构造函数的重载解析,就像对象由右值指定一样。
编译器将尝试以下步骤:
- 这个类有一个move构造函数吗?
- 如果是,要么移动它,要么忽略移动。
- 如果没有,类是否有复制构造函数?
- 如果是,移动它或省略它。
- 如果没有,我们不能复制或移动这个对象。
请注意,该类必须有移动或复制构造函数才能工作,即使省略了移动或复制。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 什么时候调用析构函数
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 是什么让放置新调用对象的构造函数?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 在C 中,对2D数组的增量是什么?函数断言(0)做什么?
- 我应该使用什么函数签名来返回对可能不存在的对象的引用
- 一个类的构造函数,为另一个类进行强制转换.将调用什么函数
- 在 opencv for c 中,什么函数与 Mat::convertTo 和 cvtColor() 完全相同
- 当按下Alt-Enter键时调用什么函数
- C库导出什么函数?
- 使用什么函数来选择文本
- c++在空类中编写和调用什么函数?
- 在共享库的构造函数(_init部分)中,如何知道什么函数被中断了?
- 我可以用什么函数来获取按钮的把手