C++ “函数到函数指针”;“衰退”;
正如我们所知,类似于C++ “函数到函数指针”;“衰退”;,c++,C++,正如我们所知,类似于void()的参数将被重写为void(*)()。这类似于数组到指针的衰减,其中int[]变为int*。在许多情况下,使用数组会将其衰减为指针。除参数外,是否存在函数“衰减”的情况 C++标准状态: §8.3.5/5 。。。在确定每个参数的类型后 类型“T数组”或“函数返回T”调整为“指针 分别指向“T”或“指向返回T的函数的指针” 因为下面的评论者似乎不相信我..下面是我的编译器显示的内容 void handler(void func()) { func(42);
void()
的参数将被重写为void(*)(
)。这类似于数组到指针的衰减,其中int[]
变为int*
。在许多情况下,使用数组会将其衰减为指针。除参数外,是否存在函数“衰减”的情况
C++标准状态:
§8.3.5/5 。。。在确定每个参数的类型后 类型“T数组”或“函数返回T”调整为“指针 分别指向“T”或“指向返回T的函数的指针” 因为下面的评论者似乎不相信我..下面是我的编译器显示的内容void handler(void func())
{
func(42);
}
main.cpp: In function 'void handler(void (*)())':
main.cpp:5:12: error: too many arguments to function
func(42);
^
是的,它们都是指针,第一个是函数指针,第二个是指向int块的指针。*看起来像一个点。数组和函数之间的另一个明显相似之处是:
void bar(string message)
{
cout << message << endl;
}
void main()
{
int myArray[10];
int* p = myArray; //array to pointer to array
void (*f)(string);
f = bar; //function to function pointer decay
}
void条(字符串消息)
{
CUT< P>当数据类型时,函数不是C和C++中的第一类公民(问题是C++,而是行为是从C继承的)。它们是代码,不是数据,它们不能被复制,作为函数传递给函数或函数返回(但所有这些都可以发生在函数指针上)。
这就是为什么函数名被视为指向该函数的指针,而不是函数体本身
使用函数(名称)而不是函数指针的可能性只是语言对程序员的一种礼貌,而不是“衰退”
数组也是如此:它们不被复制,不作为函数参数传递,也不由函数返回。而是使用它们的第一个元素的地址(复制、作为函数参数传递或由函数返回)。这就是为什么可以使用数组名而不是其第一个元素的地址,同样,这只是一种编写更少(且更少混淆)代码的方法
对于编译器来说,函数是一个不移动的内存块(包含在某个时间执行的代码),由其地址(即指向函数的指针)标识。数组也是一个数据块
它不移动,由它的地址(也是它的第一个元素的地址)标识。同样,这是一个指针
较高级别(C,C++)的函数
和数组
概念由编译器转换为较低级别(汇编程序,机器代码)理解的基本值(指针).有三种转换被认为是左值转换:左值到右值、数组到指针和函数到指针。您可以将其称为“衰减”,因为这是std::detacy
对这些类型所做的,但标准仅将其称为函数到指针转换[conv.func]:
函数类型为T
的左值可以转换为“指向T
的指针”类型的PR值。结果是指向函数的指针
如果你问函数到指针转换的情况是什么,它们基本上与其他两个左值转换的情况相同。如果我们按顺序看一下标准,下面是函数到指针转换情况的详尽列表:
将函数用作操作数[expr]/9:
每当glvalue表达式显示为期望该操作数具有prvalue的运算符的操作数时,
应用左值到右值(4.1)、数组到指针(4.2)或函数到指针(4.3)的标准转换
将表达式转换为prvalue
将函数用作varargs函数的参数,[expr.call]/7:
当给定参数没有参数时,传递参数的方式是接收函数可以通过调用va_arg
(18.10)…获取参数值。对参数表达式执行左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换
您可以static\u cast
取消此转换,[expr.static.cast]/7:
任何不包含左值到右值(4.1)的标准转换序列(第4条)的倒数,arrayto-
指针(4.2)、函数到指针(4.3)、空指针(4.10)、空成员指针(4.11)或布尔值(4.12)
转换,可以使用static\u cast
显式执行
否则,将转换传入的操作数[expr.static.cast]/8:
将左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的转换应用于
操作数
使用reinterpret\u cast
,[expr.reinterpret.cast]/1:
表达式reinterpret_cast(v)
的结果是将表达式v
转换为类型的结果
T
。如果T
是左值引用类型或函数类型的右值引用,则结果为左值;如果T
是
对对象类型的右值引用,结果为xvalue;否则,结果为prvalue和左值torvalue
(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换在
表达式v
使用const_cast
,[expr.const.cast],其措辞与上述基本相同。使用条件运算符[expr.cond]:
执行左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换
在第二个和第三个操作数上
请注意,在上述所有情况下,都是左值转换
在模板中也会发生函数到指针的转换。将函数作为非类型参数传递[temp.arg.nontype]/5.4:
对于指针指向函数类型的非类型模板参数,函数指向指针转换(4.3)
应用
或者