- 论坛徽章:
- 2
|
回复 7# bruceteen
嗯,看到int (*pf)时无法确定。
甚至对int (*pf)( ... ),如果不确定其中的内容,依然无法确定pf是:
1. 函数指针,返回int, ... 是该函数的形式参数
2. 指针,类型int*, ...是构造函数的实际参数
直到确定 ... 的内容了, 比如:
i) 0
那只能解释为指针。
ii) 1024 —— 原始例子
也只能解释为指针。然后1024这一非0整数常量初始化指针再报告一个错误。
iii) 空 —— 原始后续例子
可以解释为两者:
a) 函数指针,形式参数列表为空
b) 指针,实际参数列表为空
于是meta-rule决定是a) 而不是b)。 (假设如果meta-rule决定是b),那编译会成功的,同i),都是一个空int指针。)
iv) 前面3个例子确实是用脚丫子能想出来的
更奇葩的例子,人肉分析很容易中招的,也就是Eff STL里面提到的那种类型:
- typedef int* pint; // 为了可读性(或者说迷惑性)取个名字
- int (*p0)(pint()); // 可以解释为用 pint() 产生的临时对象(空指针)作为 p0 这个int*变量的构造函数的实际参数
- int* q = ...;
- int (*p1)(pint(q)); // 可以解释为用 pint(q) 产生的临时对象(与q相同的指针)作为p1这个int*变量的构造函数的实际参数
复制代码 但同时,p0与p1都可以解释为函数指针…… 关键点是:
- void f0(pint f()) {} // 通常写法
- void f1(pint ()) {} // 省略参数名,依然可以,这还不算太意外
- void g0(pint x ) {} // 通常的写法
- void g1(pint (x)) {} // 多加一对括号,依然可以,囧死
复制代码 所以p0又可以解释为函数指针,返回类型int,形式参数是一个省略名字的函数指针,该函数指针不接受参数并返回pint。
而p1可以解释为函数指针,返回类型int,形式参数名是q类型是pint。
最终根据meta-rule,p0,p1是指针变量(后面的括号是构造函数的实际参数列表)被排除;p0,p1都是函数指针,后面的括号都是形式参数列表。 |
|