意外地,我发现这段代码在VS2012上编译。
typedef void (*func)();
func f = func(12);
f
使用整数 12 作为其地址进行初始化。据我所知,从整数转换为函数指针是有效的,如下所示:
func f = (func)12;
而该语句看起来更像func(12)
构造函数,所以我尝试了这个:
func f(12);
并且编译失败。
func f = (func)12 //ok, cast 1
func f = func(12); //ok, what? 2
func f(12); //failed 3
func f = 12; //failed 4
所以我的问题是:
func(12)
的真正底层语法是什么,是强制转换还是初始化?- 如何用整数初始化函数指针?
- 第 4 个表达式应该编译吗?第三个呢?
让我们一一看这些:
func f = (func)12 //ok, cast 1
在这里,您将使用显式强制转换将整数值 12 强制转换为函数指针。 不允许将此强制转换作为普通隐式转换,但可以接受,因为C++可以使用reinterpret_cast
将整数和指针类型相互强制转换。 它只是不安全或便携。
func f = func(12); //ok, what? 2
这是上述语法的不同语法。 只要(type) value
和type(value)
语法是相同的type
是基元类型。
func f(12); //failed 3
在这里,您尝试创建一个初始化为值 12 的 func
类型的对象。 这种风格的对象声明仅在以下情况下才允许
- 有一个构造函数可以进行转换(不适用;
func
是基元类型(,或 - 在源类型和定义类型之间定义了隐式转换(不适用;整型和指针类型之间没有隐式转换(。
因此,编译器报告错误。
func f = 12; //failed 4
仅当存在可用于强制转换的非显式转换构造函数(不适用(或在源类型和目标类型之间定义了隐式转换(同样,不适用,因为整数和函数指针类型之间没有定义转换(时,这才有效。 因此,您会收到一个错误。
希望这有帮助!