Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

c++ - Reference to Function syntax - with and without &

What's the difference between

typedef void (&FunctionTypeR)();

vs

typedef void (FunctionType)();

Is the second also a reference to function? Is FunctionTypeR equivalent to FunctionType& when used as the type of an argument?

For

void foo(FunctionType bar)

Does the runtime makes a copy of the argument bar (a function) when foo is invoked?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...