这个数组副本如何工作?

tex*_*uce 1 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;
}
Run Code Online (Sandbox Code Playgroud)

为什么x腐烂指针?该函数应该返回一个T&并且auto应该初始化一个类型T吧?

也就是为什么ydouble[4]auto&&应该完美地转发类型,y应该是double [4] &正确的吗?

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

Bri*_*ian 6

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

auto x = return_arr(a);
Run Code Online (Sandbox Code Playgroud)

在此次通话中,T推断为double [4].所以return_arr需要引用数组,它也返回引用数组.所以这个电话真的做了同样的事情

auto x = a;
Run Code Online (Sandbox Code Playgroud)

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

auto&& y = return_arr(a);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由于引用,y推断为对数组的引用,并且不会发生衰减.所以这真的是一样的

double (&y)[4] = a;
Run Code Online (Sandbox Code Playgroud)

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

如果要复制阵列,使用memset,std::copy或如容器std::vectorstd::array.