chr*_*umb 7 c c++ function-pointers
在C中使用qsort我们传递比较函数,例如
int cmp(const void*, const void*);
Run Code Online (Sandbox Code Playgroud)
qsort的protoype期望一个int(*)(const void*,const void*)所以我们调用:
qsort(..., cmp);
Run Code Online (Sandbox Code Playgroud)
但同样有效的是:
qsort(..., &cmp);
Run Code Online (Sandbox Code Playgroud)
如果我们在C++中传入静态成员函数,这就是我们必须要做的.Kernighan&Ritchie(第2版,5.11"Pointers To Functions"p119)声明"因为[cmp]已知是一个函数,所以&运算符不是必需的,就像在数组名称之前不需要它一样. "
是否有人对此感到有点不舒服(特别是关于型号安全性)?
无论您是否感到不舒服,都不会改变C不被视为类型安全语言的事实.例证:
int main()
{
int integer = 0xFFFFFF;
void (*functionPointer)() = (void(*)())integer;
functionPointer();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这在编译时完全有效,但显然不安全.
我怀疑您只是感到不舒服,因为您不习惯像 C 允许的那样“接近金属”进行编码。C 不需要函数的地址运算符的原因是,除了调用它们或传递它们之外,您实际上无法对函数做任何事情。
换句话说,对于操作函数的“值”没有合理的定义。
而对于整数,您可以对值进行加法或减法,这对函数来说毫无意义。
无论如何,C 早于 C++ 和它自己的标准化——最初的 K&R C 甚至没有原型,ANSI 必须确保他们的标准化尽可能不破坏现有代码。
嗯,答案是按值传递函数会产生一个函数指针,就像通过值传递数组一样,会产生一个指向其第一个元素的指针.一个人说阵列和功能"衰变".只有少数情况下不会发生衰变.例如sizeof(array)产生数组的大小,而不是它的第一个元素指针之一.sizeof(函数)无效(函数不是对象),你必须做sizeof(&function).其他场合绑定参考:
void baz();
void foo(void (&bar)()) {
bar();
}
// doesnt work, since a reference to a function is requested.
// you have to pass 'bar' itself, without taking its address
// explicitely.
foo(&baz);
Run Code Online (Sandbox Code Playgroud)
这个,顺便说一句就是你能做到的
template<typename T, int N>
void ByRef(T (&foo)[N]) {
...
}
Run Code Online (Sandbox Code Playgroud)
因为在考虑参考参数时阵列还没有衰减.