之间有什么区别
typedef double F(double)
和
typdedef double (*FPT)(double);
在我看来,我可以将两者作为参数传递给函数,即
bar1(FPT f);
bar2(F f);
但我可以做到
FPT f = &foo;
我无法做到
F f = foo;
即。我不能创建F类型的变量?
答案 0 :(得分:5)
你在很多方面都是正确的。 F
是函数类型,FPT
是函数指针类型。
如果你有一个函数类型的对象,你可以获取它的地址并得到一个函数指针。但是,函数类型的对象不是真正的第一类C ++对象。只有实际的函数属于这种类型,你不能创建一个函数对象(除了通过声明一个函数!),因此你不能分配它(如F f = foo;
中所示)。
可以引用函数的唯一方法是通过函数指针或引用:
FPT f1 = &foo;
F * f2 = &foo;
F & f3 = foo;
另见this answer。
请注意,对于回调,我更喜欢指针类型的引用类型,因为与传递任何其他变量的方式相比,它更自然,并且因为您可以将地址和衰减应用于引用并获取指针,你不能用指针做什么:
double callme(F & f, double val) // not: "F *" or "FPT"
{
return f(val);
// "&f" and "std::decay<F>::type" still make sense
}
答案 1 :(得分:0)
在参数列表中,函数类型衰减到适当的函数指针类型,这样可以像参数列表一样传递相同类型的函数,它本身会衰减为相同的指针类型。
这对数组的作用相同; void foo(int arg[4])
具有实际的第一个参数类型int *
。
8.3.5函数[dcl.fct]
5 - [...]确定每个参数的类型后,任何类型为“
T
数组”或“函数返回T
”的参数都会调整为“指向{{的指针” 1}}“或”分别指向函数返回T
的指针。 [...]
在声明中使用函数类型包含在同一节中:
10 - 函数类型的typedef可用于声明函数,但不得用于定义函数。