C++ 返回非静态本地对象时,复制构造函数选择移动构造函数

C++ 返回非静态本地对象时,复制构造函数选择移动构造函数,c++,vector,g++,move-semantics,C++,Vector,G++,Move Semantics,我曾经假设一个类的move构造函数将优先于它的copy构造函数,但是在下面的代码中,似乎选择了copy构造函数,即使对象应该是可移动的 你知道为什么下面的代码在foo返回向量B时选择复制构造函数吗 包括 包括 使用名称空间std; B类{ 公众: int var_2;; Bint var:var_var { cout涉及两件事:向量再分配和再分配时的机制选择 首先,重新分配发生在这里: vector<B> foo() { vector<B> b; b.push_

我曾经假设一个类的move构造函数将优先于它的copy构造函数,但是在下面的代码中,似乎选择了copy构造函数,即使对象应该是可移动的

你知道为什么下面的代码在foo返回向量B时选择复制构造函数吗

包括 包括 使用名称空间std; B类{ 公众: int var_2;; Bint var:var_var {
cout涉及两件事:向量再分配和再分配时的机制选择

首先,重新分配发生在这里:

vector<B> foo()
{
  vector<B> b;

  b.push_back(1);
  std::cout << "Vector capacity: " << b.capacity() << " Vector size: " << b.size() << "\n";
  b.push_back(2); //capacity() == size(), reallocation is needed

  return b;
}
您可以通过提前保留空间来删除重新分配:

vector<B> foo()
{
  vector<B> b;
  b.reserve(2);
  b.push_back(1);
  b.push_back(2);

  return b;
}
或通过一次性初始化向量:

vector<B> foo()
{
  return vector<B>{1, 2};
}

涉及两件事:向量再分配和再分配时的机制选择

首先,重新分配发生在这里:

vector<B> foo()
{
  vector<B> b;

  b.push_back(1);
  std::cout << "Vector capacity: " << b.capacity() << " Vector size: " << b.size() << "\n";
  b.push_back(2); //capacity() == size(), reallocation is needed

  return b;
}
您可以通过提前保留空间来删除重新分配:

vector<B> foo()
{
  vector<B> b;
  b.reserve(2);
  b.push_back(1);
  b.push_back(2);

  return b;
}
或通过一次性初始化向量:

vector<B> foo()
{
  return vector<B>{1, 2};
}

移动向量时,其元素完全不受影响。第二次推回将导致向量大小调整和重新分配;然后将现有数据从旧数据复制到新数据。在main中添加b.reserve3;,您将看不到副本。插入向量时,向量将复制其内容以进行扩展,而与返回无关。确实如此因此,因为您的移动构造函数可能会抛出。因此它进行移动是不安全的。声明BB&&other noExcept如果您在返回b;之前打印一些内容,您将注意到在返回向量之前,所有移动和复制都已完成。谢谢大家,我学到了很多!当向量移动时,其元素完全不受影响受影响。第二次推回会导致向量大小调整和重新分配;然后将现有数据从旧数据复制到新数据。在main中添加b.reserve3;,您将看不到副本。向量复制其内容以在插入时展开,而与返回无关。这样做是因为您的移动构造函数可能会引发错误。因此,它进行移动是不安全的。声明BB&&other noexcept如果在返回b;之前打印一些内容,您将注意到在向量返回之前所有的移动和复制都已完成。谢谢大家,我学到了很多!非常感谢^^,到目前为止,我的理解是向量的RVO不是这里的问题,我使用的日志en和Middle是由B类的错误实现和在foo中的错误使用引起的,如果我错了,请让我知道谢谢你这么多^^,到目前为止我的理解是向量的RVO不是这里的问题,我看到和混淆的日志是由B类的错误实现和在foo中的错误使用引起的,如果我错了,请le我不知道