如何在函数中返回 std::vector 的引用?

ign*_*iks 1 c++

我假设向量的引用在 C++ 中无法正常工作。

例如,我将v的引用传递给change()并获取返回作为v的引用,返回的v与change()的输入不一样。这对我来说没有意义,因为我假设我们可以使用 & 进行引用调用,并将其作为对函数外的引用返回。

我用指针查看输入v和输出v的地址是否相同。但是,change() 制作了 v 的新副本并返回它,尽管我使用 & 将其作为引用返回。


如果我运行以下代码,v1 和 v2 不一样。

    #include <iostream>
    #include <vector>
    using std::cout;
    using std::endl;
    using std::vector;
    
    const vector<int>& const change(vector<int>& v) {
      v[1] = -1;             // change the elements in v
      return v;              // return a vector as reference
    }
    
    int main() {

      vector<int> v1 = {1, 2, 3, 4, 5};
      vector<int> v2 = change(v1);
    
      cout << &v1.at(0) << endl;  // check the address of v1
      cout << &v2.at(0) << endl;  // check the address of v2
    
      for (int e : v1) {
        cout << e << ",";
      }
      cout << endl;
    
      for (int e : v2) {
        cout << e << ",";
      }
      cout << endl;
      v1[4] = 10;
      v2[4] = 20;
    
      for (int e : v1) {
      cout << e << ",";
      }
      cout << endl;
      for (int e : v2) {
          cout << e << ",";
      }
        cout << endl;
    }
Run Code Online (Sandbox Code Playgroud)

结果输出:

    [result]
    000002568AA719E0
    000002568AA71B70
    1,-1,3,4,5,
    1,-1,3,4,5,
    1,-1,3,4,10,
    1,-1,3,4,20,
Run Code Online (Sandbox Code Playgroud)

v1和v2的地址不相同。这意味着 const vector& const change(vector& v) 返回 v 的副本。

我使用以下代码,但 v1 和 v2 不一样。结果对我来说没有意义。C++中有没有办法在不复制数据的情况下返回向量的引用?

    #include <iostream>
    #include <vector>
    using std::cout;
    using std::endl;
    using std::vector;
    
    const vector<int> * const change(vector<int>& v) {
        v[1] = -1;                // change the elements in v
        return &v;                // return a pointer
    }
    
    int main() {

        vector<int> v1 = {1, 2, 3, 4, 5};
        vector<int> v2 = * (change(v1));
    
        cout << &v1.at(0) << endl;   // check the address of v1
        cout << &v2.at(0) << endl;   // check the address of v2
    
        for (int e : v1) {           // print v1
          cout << e << ",";
        }
        cout << endl;
    
        for (int e : v2) {           // print v2
          cout << e << ",";
        }
        cout << endl;
        v1[4] = 10;
        v2[4] = 20;
    
        for (int e : v1) {           // print v1
          cout << e << ",";
        }
        cout << endl;
        for (int e : v2) {           // print v2 
          cout << e << ",";
        } 
        cout << endl;
    }
Run Code Online (Sandbox Code Playgroud)

结果输出:

    [result]
    000001CD273129C0
    000001CD27312600
    -1,3,4,5,
    1,-1,3,4,5,
    1,-1,3,4,10,
    1,-1,3,4,20,
Run Code Online (Sandbox Code Playgroud)

结果对我来说没有意义。

C++中有没有办法在不复制数据的情况下返回向量的引用?

for*_*818 9

v1v2是两个不同的对象。这里:

vector<int> v2 = change(v1);
Run Code Online (Sandbox Code Playgroud)

您使用v1从函数返回的引用来初始化第二个名为 的向量v2

如果您想存储从函数返回的引用(而不是初始化一个新向量),那么您需要一个引用:

const vector<int>& v2 = change(v1);
     //    ^---------------------- !!!
Run Code Online (Sandbox Code Playgroud)

请注意,它必须是const引用,因为从函数返回的引用是const


考虑这个更简单的例子,但效果相同:

#include <iostream>

int& foo(int& x) { return x;}

int main() {
  int a = 42;
  int b = foo(a);
  std::cout << &a << " " << &b;
}
Run Code Online (Sandbox Code Playgroud)

可能的输出

0x7ffc99a389ac 0x7ffc99a389a8
Run Code Online (Sandbox Code Playgroud)

这两个地址不可能相同,因为ab是两个不同的对象。另一方面,获取引用的地址会产生被引用对象的地址,因此这将打印两次相同的地址:

  int a = 42;
  int& b = foo(a);
  std::cout << &a << " " << &b;
Run Code Online (Sandbox Code Playgroud)

C++中有没有办法在不复制数据的情况下返回向量的引用?

是的。您的函数确实返回对向量的引用。当您调用 的复制构造函数时,代码中的复制就会发生v2。不过,您的函数已经在修改v1,因此无需返回引用。

  • @ignudiks——一般来说,你不会正确地学习 C++,或者至少会因为试图查看源代码来弄清楚 C++ 的工作原理而在学习 C++ 的过程中停滞不前。如果你想学习如何驾驶飞机,你就不会检查飞机发动机。 (2认同)