为什么在模板函数中数组衰减为指针?
why does the array decay to a pointer in a template function
我不明白为什么数组在模板函数中衰减为指针。
如果你看一下下面的代码:当形参被强制为引用(函数f1)时,它不会衰减。在另一个函数f中它是衰减的。为什么函数f中的T类型不是const char (buff&)[3],而是const char*(如果我理解正确的话)?
#include <iostream>
template <class T>
void f(T buff) {
std::cout << "f:buff size:" << sizeof(buff) << std::endl; //prints 4
}
template <class T>
void f1(T& buff) {
std::cout << "f:buff size:" << sizeof(buff) << std::endl; //prints 3
}
int main(int argc, char *argv[]) {
const char buff[3] = {0,0,0};
std::cout << "buff size:" << sizeof(buff) << std::endl; //prints 3
f(buff);
f1(buff);
return 0;
}
这是因为数组不能通过值传递给函数。因此,为了使它工作,数组衰变成一个指针,然后通过值传递给函数。
换句话说,按值传递数组类似于用另一个数组初始化数组,但是在c++中数组不能用数组初始化:
char buff[3] = {0,0,0};
char x[3] = buff; //error
如果一个数组出现在=
的右侧,那么左边必须是pointer
或reference
类型:
char *y = buff; //ok - pointer
char (&z)[3] = buff; //ok - reference
Demo: http://www.ideone.com/BlfSv
正是出于同样的原因,auto
在下面的每种情况下都被推断出不同(注意auto
是c++ 11的):
auto a = buff; //a is a pointer - a is same as y (above)
std::cout << sizeof(a) << std::endl; //sizeof(a) == sizeof(char*)
auto & b = buff; //b is a reference to the array - b is same as z (above)
std::cout << sizeof(b) << std::endl; //sizeof(b) == sizeof(char[3])
输出:4 //size of the pointer
3 //size of the array of 3 chars
Demo: http://www.ideone.com/aXcF5
因为数组不能作为函数参数按值传递。
当按值传递它们时,它们会衰变成指针。
在这个函数中:
template <class T>
void f(T buff) {
T不能是char (&buff)[3]
,因为这是一个引用。编译器会尝试char (buff)[3]
按值传递,但这是不允许的。因此,为了使它工作,数组衰减为指针。
第二个函数可以工作,因为这里数组是通过引用传递的:
template <class T>
void f1(T& buff) {
// Here T& => char (&buff)[3]
从规范中引用,它说
(14.8.2.1/2)如果p不是引用类型:—如果a是数组类型,由数组到指针标准转换产生的指针类型(4.2)代替A进行类型扣除;否则
那么,就你的情况而言,很明显,
template <class T>
void f1(T& buff) {
std::cout << "f:buff size:" << sizeof(buff) << std::endl; //prints 3
}
不退化为指针
因为函数不能用数组作为参数。它们可以有数组引用
原因主要归结为匹配不同的重载时的类型推断。当您调用f
时,编译器将类型推断为const char[3]
,然后衰减为const char*
,因为就是数组所做的。这与f(1)
中编译器将T推断为int
而不是int&
的方式完全相同。
在f1
的情况下,因为实参是通过引用获取的,那么编译器再次将T推断为const char[3]
,但它接受了对它的引用。
没有什么令人惊讶的,但如果不是因为数组的在用作函数参数时将衰变为指针,则相当一致…
- 为什么这些函数不衰减到函数指针?
- 为什么多维数组中的空字符串文本衰减为空指针?
- 从原始指针(衰减的 C 样式数组)和大小生成范围::视图
- 数组变量衰减为指针
- 如果我只有指向第一个数组元素的指针,考虑到数组衰减,是否可以找到数组的长度?
- 在分配给指针到固定数组期间没有指针衰减
- 如果一个函数通过引用返回一个数组,它是指针的衰减吗?
- 推断衰减到函数指针的 lambda 类型
- 应该非捕获通用的lambdas衰减以发挥指针
- 数组衰减为指针和重载分辨率
- 运行时大小的数组和指针衰减
- 编译器在数组到指针衰减存储中生成的指针在哪里
- 为什么指针衰减优先于推导的模板
- 有没有办法避免数组到指针衰减
- 为什么数组类型不会衰减到类模板的指针
- 我能逆转数组到指针衰减的过程吗?
- 数组到指针衰减问题
- 为什么在模板函数中数组衰减为指针?
- 数组衰减为Lambda指针
- 如果通过模板函数中的 const 引用传递,数组不会衰减到指针