C++ 这将执行默认的移动操作吗

C++ 这将执行默认的移动操作吗,c++,c++11,move,C++,C++11,Move,我有一个函数foo: std::vector<T> foo() { std::vector<T> result; // populate result { /* for loop with result.push_back(). ignore real code. */ } // return result; <-- note there without std::move } 对于这种情况

我有一个函数foo:

std::vector<T> foo() {
  std::vector<T> result;
  // populate result
  {
    /*
       for loop with result.push_back().
       ignore real code.
    */
  }
  //
  return result;    <-- note there without std::move
}

对于这种情况,foo()函数创建一个临时结果。现在,由于v是一个引用,它不能将结果移动到v。因此,它需要创建一个新副本。我的理解正确吗?

对于这两种情况,似乎没有额外的副本,从这里可以看出,编译器可以通过应用

但是,似乎规则的一个例外是:编译器可能会删除对移动和复制构造函数的调用以及对临时对象的析构函数的匹配调用,即使这些调用有明显的副作用。要观察这些副作用,您必须在编译时使用
-fno elide构造函数
选项

从这一页中,我们应该看到以下条款:

在return语句中,当操作数是非易失性 具有自动存储持续时间的对象,该存储持续时间不是函数 参数或catch子句参数,并且属于同一类 类型(忽略cv限定)作为函数返回类型。这 拷贝省略的变体称为NRVO,“名为返回值” 优化”

当编译器看到下面的结构时,它知道它是NRVO的候选结构

T FunctionName ( ... )
{
    T a;
    ...
    return a;
}
与问题的代码结构相匹配

std::vector<T> foo() {
  std::vector<T> result;
  // populate result
  {
    /*
       for loop with result.push_back().
       ignore real code.
    */
  }
  return result;
}
std::vector foo(){ std::向量结果; //填充结果 { /* 对于结果为的循环。向后推_()。 忽略真实代码。 */ } 返回结果; } 案例1-

const auto v = foo();   <-- will it move the vector by default?

const auto v=foo();你是在问他是否会在这里工作?您可以尝试打印
result
v
的地址,以检查它们是否指向同一位置。据我所知,他们正在打印同一个地址。所以一个很好的猜测是,没有复制。对于这两种情况?对于第二种情况,v被定义为const auto&v?@badola。对于这两种情况,我们似乎都不做额外的复制。我很好奇编译器是如何知道第二种情况的?
const&
被允许绑定到临时的。NRVO是可选的。
std::vector<T> foo() {
  std::vector<T> result;
  // populate result
  {
    /*
       for loop with result.push_back().
       ignore real code.
    */
  }
  return result;
}
const auto v = foo();   <-- will it move the vector by default?
const auto &v = foo();  <-- same question as above, assuming T is movable