更新时间:2022-12-27 09:31:43
不同之处在于不能创建函数类型的对象,但是可以创建函数指针类型。
这意味着如果你有一个函数,说 f ()
as:
void f(){}
那么这里是你能做什么,你不能做什么:
FunctionType fun1 = f; //错误 - 无法创建函数类型的对象
FunctionType * fun2 = f; // ok
FunctionTypeR fun3 = f; // ok
测试代码:
typedef void(& FunctionTypeR)();
typedef void FunctionType();
void f(){}
int main(){
FunctionType fun1 = f; //错误 - 无法创建函数类型的对象
FunctionType * fun2 = f; // ok
FunctionTypeR fun3 = f; // ok
return 0;
}
现在看到编译错误(和警告):
prog.cpp:在函数'int main()':
prog.cpp:7:error:function'void fun1被初始化为一个变量
prog.cpp:8:warning:unused variable'fun2'
prog.cpp:9:warning:unused variable'fun3'
在线演示: http://ideone.com/hpTEv
但是,如果使用 FunctionType
类型)在函数参数列表中:
void foo(FunctionType bar);
那么它等效于
void foo(FunctionType * bar);
这意味着,无论你写什么,都可以使用 bar
as:
bar // ok
(* bar)(); // ok
也就是说,您可以这样写:
void h(FunctionType fun){fun(); }
void g(FunctionType fun){(* fun)(); }
这是因为函数类型为函数指针类型调整; :
$ pre>函数类型|函数指针类型(调整类型)
void()| void(*)()
void(int)| void(*)(int)
int(int,int)| int(*)(int,int)
.... | ...等等。
C ++ 03标准在§13.1/ >
参数声明的区别仅在于一个是函数类型,另一个是指向相同函数类型的指针等效。 也就是说,函数类型会调整为指向函数类型(8.3.5)的指针。
[示例:
void h(int());
void h(int(*)()); //重定义h(int())
void h(int x()){} // h(int())的定义
void h(int(* x)()){ } //形式不正确:redefinition of h(int())
]
如果您使用`FunctionTypeR
(这是一个函数引用类型):
void foo(FunctionTypeR bar);
那么它等效于:
void foo(FunctionType *& bar);
并且,
code> void h(FunctionTypeR fun){fun(); }
void g(FunctionTypeR fun){(* fun)(); }
您可以使用FunctionType 声明一个函数(但不能定义)。
p>
struct A
{
//成员函数声明。
FunctionType f; //等价于:void f();
};
void A :: f()// definition
{
std :: cout< haha< std :: endl;
}
//转发声明
FunctionType h; //等价于:void h();
int main(){
A a;
a.f(); //调用成员函数
h(); //调用非成员函数
}
void h()//定义在main()之下
{
std :: cout< hmmm ..< std :: endl;
}
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