我随机编写了接受数组引用并返回数组的函数,并从旧数组初始化一个新数组:
#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吗?
为什么y
是double[4]
? auto&&
应该完全转发类型,y应该是double [4] &
权利吗?
有人可以解释为什么所有这些都发生了吗?
答案 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;
这是一个参考初始化。同样,不会复制数组。
如果要复制数组,请使用memset
,std::copy
或std::vector
或std::array
等容器。