【问题标题】:Will returning a vector<vector <int> > from a function invoke any move constructors in C++11将从函数返回向量<vector <int> > 调用 C++11 中的任何移动构造函数
【发布时间】:2013-11-18 08:25:02
【问题描述】:

在 C++11 中,是否会从调用任何移动构造函数的函数返回 vector&lt;vector&lt;int&gt; &gt;?或者下面的代码是否只是制作所有向量及其元素的另一个副本?

vector< vector<int> > Func() {
  vector< vector<int> > vec;
  //vec is filled here
  return vec;
}

对于简单类型的 stl 容器,当从函数中将它们作为值返回时,是否可以找到何时使用移动构造函数或进行复制?

【问题讨论】:

    标签: c++ c++11 move-semantics


    【解决方案1】:

    return 语句被标准特别涵盖,以自动视为移动。所以是的,这将调用移动构造函数。

    这方面的法律条文是 C++11,[class.copy]§31+32

    31 当满足某些条件时,允许实现省略类对象的复制/移动构造......这种复制/移动操作的省略,称为复制省略, 在以下情况下是允许的(可以合并以消除多个副本):

    • 在具有类返回类型的函数的 return 语句中,当表达式是具有与函数返回类型相同的 cvunqualified 类型的非易失性自动对象(函数或 catch 子句参数除外)的名称时, 可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作
    • ...

    32 当满足或将满足省略复制操作的条件时,除了源对象是函数参数,并且要复制的对象由左值指定, 首先执行为复制选择构造函数的重载解析,就好像对象由右值指定一样。如果重载解析失败,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是 cv 限定的),再次执行重载决议,将对象视为左值。 ...

    (强调我的)

    结合并应用于您的情况,这意味着当从函数返回局部变量时,首先尝试移动,并且只有在不可能的情况下才会执行复制。

    (而且,正如@BjornPollex 指出的那样,很可能甚至会忽略这一举动)

    【讨论】:

    • 在 OP 显示的特定代码中,NRVO 可以优化掉任何副本或移动。
    • 函数本身会忽略移动。是否可以在调用者中省略取决于它是否是接收变量的第一次初始化。
    • @BjörnPollex 很有可能。但是 (N)RVO 始终是可选的,而首先尝试移动是标准要求的
    猜你喜欢
    • 2018-01-23
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2016-11-11
    • 1970-01-01
    相关资源
    最近更新 更多