Reference to Function syntax - with and without &

前端 未结 1 1431
一向
一向 2020-12-19 05:36

What\'s the difference between

typedef void (&FunctionTypeR)();

vs

typedef void (FunctionType)();

Is

相关标签:
1条回答
  • 2020-12-19 05:43

    The difference is that you cannot create objects of function type, but you can create of objects of function pointer type, and function reference type.

    That means if you've a function, say f() as:

     void f(){}
    

    then here is what you can do, and what you cannot do:

    FunctionType  fun1 = f; //error - cannot create object of function type
    FunctionType *fun2 = f; //ok 
    FunctionTypeR fun3 = f; //ok
    

    Test code:

    typedef void (&FunctionTypeR)();
    typedef void FunctionType();
    
    void f(){}
    
    int main() {
            FunctionType  fun1 = f; //error - cannot create object of function type
            FunctionType *fun2 = f; //ok 
            FunctionTypeR fun3 = f; //ok
            return 0;
    }
    

    Now see the compilation error (and warnings):

     prog.cpp: In function ‘int main()’:
     prog.cpp:7: error: function ‘void fun1()’ is initialized like a variable
     prog.cpp:8: warning: unused variable ‘fun2’
     prog.cpp:9: warning: unused variable ‘fun3’
    

    Online demo : http://ideone.com/hpTEv


    However, if you use FunctionType (which is a function type) in a function parameter list as:

    void foo(FunctionType bar);
    

    then it's equivalent to

    void foo(FunctionType * bar);
    

    That means, no matter what you write, you can call the function using bar as:

       bar();  //ok
     (*bar)(); //ok 
    

    That is, you can write this:

    void h(FunctionType fun) { fun(); }
    void g(FunctionType fun) { (*fun)(); }
    

    Demo : http://ideone.com/kwUE9

    This is due to function type to function pointer type adjustment; that is, the function type is adjusted to become a pointer to function type:

    Function type     |  Function pointer type (adjusted type)
       void ()        |     void (*)()
       void (int)     |     void (*)(int)
       int  (int,int) |     int  (*)(int,int)
       ....           |      ... so on
    

    The C++03 Standard says in §13.1/3,

    Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (8.3.5).

    [Example:
        void h(int());
        void h(int (*)()); // redeclaration of h(int())
        void h(int x()) { } // definition of h(int())
        void h(int (*x)()) { } // ill-formed: redefinition of h(int())
    ]
    

    And if you use `FunctionTypeR (which is a function reference type) as:

    void foo(FunctionTypeR bar);
    

    then it's equivalent to:

    void foo(FunctionType * & bar);
    

    And,

    void h(FunctionTypeR fun) { fun(); }
    void g(FunctionTypeR fun) { (*fun)(); }
    

    Demo : http://ideone.com/SmtQv


    Interesting part...

    You can use FunctionType to declare a function (but not to define it).

    For example,

    struct A
    {
       //member function declaration. 
        FunctionType f; //equivalent to : void f();
    };
    
    void A::f() //definition
    {
      std::cout << "haha" << std::endl;
    }
    
    //forward declaration
    FunctionType h; //equivalent to : void h();
    
    int main() {
            A a;
            a.f(); //call member function
            h();   //call non-member function
    }
    
    void h() //definition goes below main()
    {
       std::cout <<"hmmm.." << std::endl;
    }
    

    Demo : http://ideone.com/W4ED2

    0 讨论(0)
提交回复
热议问题