C++语法/语义问题:对Function和typedef关键字的引用



typedef int (&rifii) (int, int)的用途是什么?

这个"语句"之前的typedef是做什么的?我想把它看作

typedef (int (&rifii) (int, int)) [new name]

但[新名称]不在那里,就像你做一样

typedef int INTEGER;

以下语法的类似问题:

typedef void (*PF) ();
PF edit_ops[ ] = { &cut, &paste, &copy, &search };
PF file_ops[ ] = { &open, &append, & close, &write };
PF* button2 = edit_ops;
PF* button3 = file_ops;
button2[2]( );

typedef允许什么?它能让你不必打字吗:

void (*PF) ();
(void (*PF) ()) edit_ops[ ] = { &cut, &paste, &copy, &search };
(void (*PF) ()) file_ops[ ] = { &open, &append, & close, &write };
(void (*PF) ())* button2 = edit_ops;
(void (*PF) ())* button3 = file_ops;

如果是这样的话,typedef的第二部分([你想要的](发生了什么:

typedef [what you have -- (FP)] [what you want]

非常感谢对此事的澄清。

Typedef不像typedef [type] [new name]那样工作。[new name]部分并不总是出现在末尾。

您应该这样看:如果[some declaration]声明了一个变量,那么typedef [same declaration]将定义一个类型。

例如:

  • int x;声明一个名为x的变量,类型为int->typedef int x;将类型x定义为int
  • struct { char c; } s;定义了一个名为s的变量,该变量属于某个结构类型->typedef struct { char c; } s;将类型s定义为某个结构型
  • int *p;声明了一个名为p的变量,其类型为指向int->typedef int *p;将类型p定义为指向int的指针

还有:

  • int A[];声明了一个名为A->typedef int A[];的int数组,并将类型A声明为int数组
  • int f();声明一个名为f的函数->typedef int f();声明一个函数类型f为返回int且不接受参数
  • int g(int);声明函数名g->typedef int g(int);声明函数类型g为返回一个int并取一个int

顺便说一句:注意,所有函数参数都在新名称后面!由于这些类型也可能很复杂,因此[新名称]后面可能会有很多文本。可悲的是,这是真的。

但这些还不是适当的函数指针,只是函数类型。我不确定函数类型是否存在于C或C++中,但作为我解释的中间步骤,它很有用。

要创建一个真正的函数指针,我们必须在名称中添加"*"。遗憾的是,它有错误的优先级:

  • typedef int *pf();声明一个函数类型pf作为返回一个int*。哎呀,这不是我们的本意

因此使用((分组:

  • typedef int (*pf)();将函数指针类型pf声明为返回int,不接受任何参数
  • typedef int (&rf)();将函数引用类型rf声明为返回int并且不接受任何参数

现在让我们看看你的例子并回答你的问题:

typedef int (&rifii) (int, int);将函数引用类型rifii声明为返回一个int并接受两个int参数。

显然(?(button2[2]( );将调用copy();

没有typedefs的正确语法在没有编译器的情况下很难正确书写,即使有编译器也很难阅读:

void (*edit_ops[])() = { &cut, &paste, &copy, &search }; 
void (*file_ops[])() = { &open, &append, & close, &write };
void (**button2)() = edit_ops;
void (**button3)() = file_ops;
button2[2]( );   

这就是为什么每个人在使用函数指针时都喜欢typedef的原因。

阅读时,找个地方开始阅读。尽可能向右阅读,但要观察((的分组。然后尽可能向左阅读,再次受到分组((的限制。完成((中的所有内容后,先向右阅读,然后向左阅读。

应用于void (*edit_ops[])(),这意味着

  1. edit_ops为(向右(
  2. 数组(打到小组的最后,所以向左转弯(
  3. 的指针(分组结束(
  4. 到函数获取(将((解析到右侧(
  5. 没有自变量(向左(
  6. 返回空白

对于专家:更为复杂的是,参数可以有名称(将被忽略(,因此甚至很难找到从哪里开始解析!例如,typedef int (*fp)(int x);是有效的,与typedef int (*fp)(int);相同。名称周围甚至可以有((:typedef int (*fp)(int (x));但正如我们所看到的,参数名称可以省略,因此甚至允许以下内容:typedef int (*fp)(int ());。这仍然是一个函数指针,取一个int并返回一个int。如果你想让你的代码变得很难阅读。。。

edit:很抱歉,第一个答案没有初始化fcn-ptr。

typedef int(&rifii((int,int(允许您声明函数指针,这些指针通过引用返回一个int,并将两个int作为参数。

    rifi x,y,z;
int &ret_an_int_ref( int p1, int p2 ) { 
    static int retval=0;
    if( p1 > p2 ) retval = p1*p2;
    return retval;
}
    x = ret_an_int_ref;
    y = ret_an_int_ref;
int & an_int_ref = x(1,2);
int & another_int_ref=y(3,4);
z = x;
z(1,2); // will give the same answer as x(1,2);

最新更新