这个数组副本如何工作?

时间:2014-02-25 19:09:34

标签: c++ c++11

我随机编写了接受数组引用并返回数组的函数,并从旧数组初始化一个新数组:

#include <iterator>
#include <iostream>

using namespace std;

template <typename T>
T& return_arr(T& arr) {
    return arr;
}

int main(){
    double a[] = {1,2,4.5,9};
    auto x = return_arr(a);
    a[2] = 5;
    cout << x[2] << endl;
    //x.dummy_error(); // If this one is uncommented, the compiler says x is a double*
    auto&& y = return_arr(a);
    a[3] = 10;
    cout << y[3] << endl;
    //y.dummy_error(); // If this one is uncommented, the compiler says y is a double[4]

    return 0;
}

为什么x会被指针腐烂?该函数应该返回T&auto应该初始化类型T吗?

为什么ydouble[4]auto&&应该完全转发类型,y应该是double [4] &权利吗?

有人可以解释为什么所有这些都发生了吗?

1 个答案:

答案 0 :(得分:6)

您无法在C ++中按值传递或返回数组。抱歉---你不能。

auto x = return_arr(a);

在此次通话中,T被推断为double [4]。因此return_arr引用到数组,它还会返回对数组的引用。所以这个电话真的和

一样
auto x = a;

x推断为double*。这是因为auto使用与模板相同的类型推导规则,并且当参数是数组时,非推荐模板类型参数被推导为指针。换句话说,这里发生衰变,正如您通常所期望的那样。

auto&& y = return_arr(a);

在这种情况下,由于引用,y被推断为对数组的引用,并且不会发生衰减。所以这与

完全相同
double (&y)[4] = a;

这是一个参考初始化。同样,不会复制数组。

如果要复制数组,请使用memsetstd::copystd::vectorstd::array等容器。