开发者

C++ Syntax/Semantics Question: Reference to Function and typedef keyword

What would typedef int (&rifii) (int, int) be used for?

What is the typedef before this "statement" do? I want to think of this as

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

but the [new name] is not there like if you do

typedef int INTEGER;

Similar question for the following syntax:

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]( );

What is the typedef allowing? Is it making it so you don't have to type:

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;

If so what happend to the second part ([what you want]) of the typedef like in:

typedef [what you have -- (FP)] [what you wa开发者_运维百科nt]

Clarification on this matter is greatly appreciated.


Typedef does not work like typedef [type] [new name]. The [new name] part does not always come at the end.

You should look at it this way: if [some declaration] declares a variable, typedef [same declaration] would define a type.

E.g.:

  • int x; declares a variable named x of type int -> typedef int x; defines a type x as int.
  • struct { char c; } s; defines a variable named s of some struct type -> typedef struct { char c; } s; defines type s to be some struct type.
  • int *p; declares a variable named p of type pointer to int -> typedef int *p; defines a type p as pointer to int.

And also:

  • int A[]; declares an array of ints named A -> typedef int A[]; declares a type A as an array of ints.
  • int f(); declares a function named f -> typedef int f(); declares a function type f as returning an int and taking no arguments.
  • int g(int); declares a function name g -> typedef int g(int); declares a function type g as returning an int and taking one int.

As an aside: Note that all function arguments come after the new name! As those types could be complicated as well, there can be a lot of text after the [new name]. Sadly, but true.

But those are not proper function pointers yet, just function types. I'm not sure a function type exists in C or C++, but it is useful as an intermediate step in my explanation.

To create a real function pointer, we have to add '*' to the name. Which, sadly, has wrong precedence:

  • typedef int *pf(); declares a function type pf as return a int*. Oops, that's not what was intended.

So use () to group:

  • typedef int (*pf)(); declares a function pointer type pf as returning an int and taking no arguments.
  • typedef int (&rf)(); declares a function reference type rf as returning an int and taking no arguments.

Let's now look at your examples and answer your questions:

typedef int (&rifii) (int, int); declares a function reference type rifii as returning an int and taking two int arguments.

And obviously (?) button2[2]( ); will call copy();.

Proper syntax without typedefs is hard to write correctly without a compiler, and hard to read even with a compiler:

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

void (**button2)() = edit_ops;
void (**button3)() = file_ops;

button2[2]( );   

Which is why everyone prefers typedefs when using function pointers.

When reading, find the place to start reading. Read as much to the right as you can, but observe the grouping by (). Then read to the left as much as you can, again limited by grouping (). After finishing everything inside the (), start with reading to the right, then to the left.

Applied to void (*edit_ops[])(), this means that

  1. edit_ops is (go to the right)
  2. an array (hit the end of the group, so turn to the left)
  3. of pointer (end of grouping)
  4. to a function taking (parse the () to the right)
  5. no arguments (go to the left)
  6. returning a void

For the experts: To make it even more complicated, arguments can have names (which will be ignored), so it might even be hard to find where to start parsing! E.g. typedef int (*fp)(int x); is valid and the same as typedef int (*fp)(int); Names can even have () around them: typedef int (*fp)(int (x)); But as we have seen, argument names can be left out, so even the following is allowed: typedef int (*fp)(int ());. This is still a function pointer taking a single int and return an int. In case you would like to make your code really hard to read...


edit: sorry first answer didn't initialize the fcn ptr.

typedef int (&rifii) (int, int) allows you to declare function pointers that return an int by reference and take two ints as parameters.

    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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜