5
#include <iostream>

typedef char (*callback)(int *data);
typedef char (callback2)(int *data);
typedef char callback3(int *data);

char fun_a(int *d)
{
    if (*d == 10)
        return 'A';
    else
        return 'B';
}

int main()
{
    int num = 10;
    callback cb_1_a;
    cb_1_a = fun_a;
    std::cout << cb_1_a(&num) << std::endl;

    callback cb_1_b;
    cb_1_b = &fun_a;
    std::cout << cb_1_b(&num) << std::endl;

    callback cb_1_c;
    cb_1_c = &fun_a;
    std::cout << (*cb_1_c)(&num) << std::endl;

    /*
    callback2 cb2;
    cb2 = fun_a;    // wrong

    callback3 cb3;
    cb3 = fun_a;    // wrong
    */

    return 0;
}

C++ compiler doesn't complain about the typedef of callback2 and callback3.

Question> What do typedef char (callback2)(int *data) and typedef char (callback3)(int *data) mean? Is there a use case where I can apply them?

q0987
  • 34,938
  • 69
  • 242
  • 387

2 Answers2

6

Your first typedef defines callback as a pointer to a function that takes an int* argument and returns a char value. So, being a pointer, you can assign a value (the address of an appropriate function) to variables of that type, as you do in the case of your cb_1_a, cb_1_b and cb_1_c variables; in the first case (cb_1_a = fun_a;), you are using the function's name (but note: without the parentheses) in place of using an explicit & operator (if you add the parentheses after a function name, then your are invoking that function).

Your second and third typedef statements define their types as actual functions, and you cannot assign a value to a function. Also, as you have nothing other than the name callback2 inside the first set of parentheses in typedef char (callback2)(int* data);, those parentheses are actually redundant, and the type is equivalent to that defined in the next line: typedef char callback3(int* data);.

However, you can use the second two types (indirectly) to declare function pointers, by adding the * in the relevant variable declarations, like this:

    //...
    callback2 *cb2; // cb2 is now a POINTER to a "callback2" type!
    cb2 = fun_a;    // So this is OK - We assign the ADDRESS of fun_a to the cb2 pointer
    callback3 *cb3; // And the same here...
    cb3 = fun_a;    // ...and here
    //...

Feel free to ask for further clarification and/or explanation. Also, you may find this post helpful, in terms of using typedef and function pointer syntax: Typedef function pointer?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
5

This is a little easier to understand with using syntax. You have 2 using statements here:

using A = char (*) (int*);
using B = char (int*);

(Note that your 2nd and 3rd examples are equivalent).

A is a function-pointer type. In particular, objects of this type can be used to store the address of any function that takes an int* and returns a char:

char f(int*);
A a = f;

a can now be used similarly to f as you've shown in your examples.

B is a function type, i.e. it declares a function that takes an int* and returns a char. So this line:

B b;

is the same as declaring a function b like this:

char b(int*);

There's not really much you can do with this, at least in an evaluated context, as I don't think there's any way to provide a definition for this function declaration.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
cigien
  • 57,834
  • 11
  • 73
  • 112
  • I found a use case: [Comparing std::functions for equality?](https://stackoverflow.com/a/35920804/8705305) – radj307 Sep 03 '22 at 16:56