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?
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With