为什么只有指向函数的指针而不是函数的var?
Why is there only pointer to function instead of var of function?
在C/C++中,我们可以declare/define一个类型的函数指针,然后declare/define这个类型的一些变量。
但是我觉得是歧义。
例如:
typedef void ( *pFunc )();
// typedef void ( aFunc )();
void theFunc() {
cout << "theFunc has been called successfully." << endl;
};
int main() {
pFunc pf0 = theFunc;
pFunc pf1 = &theFunc;
pf0();
( *pf0 )();
pf1();
( *pf1 )();
};
理论上只有pFunc pf1 = &theFunc;
和(*pf1)();
是合法的,但以上都可以通过编译
在Pascal syntax中,我们需要分别定义函数的vars或函数指针的vars,它们的含义是不同的,而且更清晰(至少我是这么认为的)!
此外,我们不能declare/define一个函数的var而不是函数指针的var!
我尝试了以下但失败了。
typedef void ( aFunc )();
aFunc af0 = theFunc;
如果与其他类型如int/double,则有非常严格的语法限制我们正确使用它们。 (如果int*
和int
不一样,为什么*pf0
和pf0
一样?!)
所以,我可以认为这是 C/C++ 标准的错误吗?
一些声明的类型:
// decltype of theFunc is void ()
// decltype of &theFunc is void (*) ()
// decltype of *theFunc is void (&) ()
现在,关于您的代码,由于函数可以隐式转换为指向该函数的指针,我们有:
using pFunc = void(*)();
using rFunc = void(&)();
pFunc p_fct = &theFunc; // no conversion
pFunc p_fct = theFunc; // conversion lvalue to pointer
pFunc p_fct = *theFunc; // conversion lvalue reference to pointer
rFunc r_fct = *theFunc; // no conversion
rFunc r_fct = theFunc; // conversion lvalue to lvalue reference
rFunc r_fct = &theFunc; // ERROR: conversion pointer to lvalue reference not allowed
到目前为止的转化。现在,任何 pFunc
或 rFunc
类型的对象都是可调用对象。另外,请注意 (*p_fct)
和 (*r_fct)
都是 rFunc
类型。因此,您可以按照问题中的描述调用您的函数:
p_fct(); // callable object of type pFunc
r_fct(); // callable object of type rFunc
(*p_fct)(); // callable object of type rFunc
(*r_fct)(); // callable object of type rFunc
注意下面和上面的是等价的:
using Func = void ();
Func* p_fct = &theFunc; // no conversion
Func& r_fct = *theFunc; // no conversion
p_fct(); // callable of type Func* or pFunc
r_fct(); // callablel of type Func& or rFunc
EDIT 回答问题:"why them was arranged in this way" 来自以下评论:无法复制函数(如@JohnBurger 的回答中所述)。这就是为什么您的代码:
typedef void ( aFunc )();
aFunc af0 = theFunc;
不起作用。如上所述,您可以执行以下操作:
typedef void ( aFunc )();
aFunc* af0 = &theFunc; // or theFunc, or even *theFunc
或者您可以这样做:
auto myFct = theFunc;
但请记住 myFct
的 decltype
仍然是 void (*)()
。
暂时忽略函数:考虑 struct
.
您可以有一个 struct
,或一个指向 struct
的指针:
typedef struct {
int x;
int y;
} Point;
Point origin = { 0, 0 };
Point here = { 1, 1 };
Point there = { 2, 2 };
int main() {
Point centre = origin;
Point *myPoint = &origin;
centre = here;
myPoint = &here;
centre = there;
myPoint = &there;
} // main()
共有三个全局 Point
:origin
、here
和 there
。
main()
有两个变量:centre
和 myPoint
.
centre
复制 origin
、here
和 there
的值。
myPoint
指向 origin
、here
和there
- 它不 复制它们。
这两种思路有很大区别:一种是复制整个对象,而另一种只指向另一个对象。
现在想想函数。函数由编译器在代码中定义,永远不会被复制。所以函数变量 no 有意义——它们有多大?唯一明智的想法是指向函数的指针 - 这就是 C 语言提供的全部内容。
如果要定义 C 函数 typedef
,请使用以下语法:
// Fn is a function that accepts a char and returns an int
int Fn(char c);
// FnType is the type of a function that accepts a char and returns an int
typedef int FnType(char c);
// Here is the definition of Fn
int Fn(char c) {
return c + 1;
} // Fn(c)
// Now here is how you can use FnType
int main() {
FnType *fn = &Fn;
return fn('A');
} // main()
我想我找到了答案。
确实,c++ 标准提供了一种无需指针帮助即可声明函数类型的方法。
示例:
#include <functional>
using AFunc_t = function<void( int )>;
void theFunc( int );
AFunc_t afunc = theFunc;
我希望这对某人有所帮助。
在C/C++中,我们可以declare/define一个类型的函数指针,然后declare/define这个类型的一些变量。 但是我觉得是歧义。
例如:
typedef void ( *pFunc )();
// typedef void ( aFunc )();
void theFunc() {
cout << "theFunc has been called successfully." << endl;
};
int main() {
pFunc pf0 = theFunc;
pFunc pf1 = &theFunc;
pf0();
( *pf0 )();
pf1();
( *pf1 )();
};
理论上只有pFunc pf1 = &theFunc;
和(*pf1)();
是合法的,但以上都可以通过编译
在Pascal syntax中,我们需要分别定义函数的vars或函数指针的vars,它们的含义是不同的,而且更清晰(至少我是这么认为的)!
此外,我们不能declare/define一个函数的var而不是函数指针的var! 我尝试了以下但失败了。
typedef void ( aFunc )();
aFunc af0 = theFunc;
如果与其他类型如int/double,则有非常严格的语法限制我们正确使用它们。 (如果int*
和int
不一样,为什么*pf0
和pf0
一样?!)
所以,我可以认为这是 C/C++ 标准的错误吗?
一些声明的类型:
// decltype of theFunc is void ()
// decltype of &theFunc is void (*) ()
// decltype of *theFunc is void (&) ()
现在,关于您的代码,由于函数可以隐式转换为指向该函数的指针,我们有:
using pFunc = void(*)();
using rFunc = void(&)();
pFunc p_fct = &theFunc; // no conversion
pFunc p_fct = theFunc; // conversion lvalue to pointer
pFunc p_fct = *theFunc; // conversion lvalue reference to pointer
rFunc r_fct = *theFunc; // no conversion
rFunc r_fct = theFunc; // conversion lvalue to lvalue reference
rFunc r_fct = &theFunc; // ERROR: conversion pointer to lvalue reference not allowed
到目前为止的转化。现在,任何 pFunc
或 rFunc
类型的对象都是可调用对象。另外,请注意 (*p_fct)
和 (*r_fct)
都是 rFunc
类型。因此,您可以按照问题中的描述调用您的函数:
p_fct(); // callable object of type pFunc
r_fct(); // callable object of type rFunc
(*p_fct)(); // callable object of type rFunc
(*r_fct)(); // callable object of type rFunc
注意下面和上面的是等价的:
using Func = void ();
Func* p_fct = &theFunc; // no conversion
Func& r_fct = *theFunc; // no conversion
p_fct(); // callable of type Func* or pFunc
r_fct(); // callablel of type Func& or rFunc
EDIT 回答问题:"why them was arranged in this way" 来自以下评论:无法复制函数(如@JohnBurger 的回答中所述)。这就是为什么您的代码:
typedef void ( aFunc )();
aFunc af0 = theFunc;
不起作用。如上所述,您可以执行以下操作:
typedef void ( aFunc )();
aFunc* af0 = &theFunc; // or theFunc, or even *theFunc
或者您可以这样做:
auto myFct = theFunc;
但请记住 myFct
的 decltype
仍然是 void (*)()
。
暂时忽略函数:考虑 struct
.
您可以有一个 struct
,或一个指向 struct
的指针:
typedef struct {
int x;
int y;
} Point;
Point origin = { 0, 0 };
Point here = { 1, 1 };
Point there = { 2, 2 };
int main() {
Point centre = origin;
Point *myPoint = &origin;
centre = here;
myPoint = &here;
centre = there;
myPoint = &there;
} // main()
共有三个全局 Point
:origin
、here
和 there
。
main()
有两个变量:centre
和 myPoint
.
centre
复制 origin
、here
和 there
的值。
myPoint
指向 origin
、here
和there
- 它不 复制它们。
这两种思路有很大区别:一种是复制整个对象,而另一种只指向另一个对象。
现在想想函数。函数由编译器在代码中定义,永远不会被复制。所以函数变量 no 有意义——它们有多大?唯一明智的想法是指向函数的指针 - 这就是 C 语言提供的全部内容。
如果要定义 C 函数 typedef
,请使用以下语法:
// Fn is a function that accepts a char and returns an int
int Fn(char c);
// FnType is the type of a function that accepts a char and returns an int
typedef int FnType(char c);
// Here is the definition of Fn
int Fn(char c) {
return c + 1;
} // Fn(c)
// Now here is how you can use FnType
int main() {
FnType *fn = &Fn;
return fn('A');
} // main()
我想我找到了答案。
确实,c++ 标准提供了一种无需指针帮助即可声明函数类型的方法。
示例:
#include <functional>
using AFunc_t = function<void( int )>;
void theFunc( int );
AFunc_t afunc = theFunc;
我希望这对某人有所帮助。