当我看到这条线时,我正在看this post。
简而言之,代码如下:
struct cell {
typedef cell (*proc_type)(const std::vector<cell> &);
typedef std::vector<cell>::const_iterator iter;
typedef std::map<std::string, cell> map;
cell_type type;
std::string val;
std::vector<cell> list;
proc_type proc;
environment * env;
cell(cell_type type = Symbol) : type(type), env(0) {}
cell(cell_type type, const std::string & val) : type(type), val(val), env(0) {}
cell(proc_type proc) : type(Proc), proc(proc), env(0) {}
};
那么typedef cell(* proc_type)是什么(const std :: vector&amp;);怎么办?
typedef应该像
typedef (existing) (new)
那么为什么在我们只能使用单元格时声明这么复杂的新类型?
答案 0 :(得分:2)
你的断言“typedef应该像typedef (existing) (new)
一样使用”是完全错误的。不,一般情况下不会那样使用。只有最基本的typedef声明可能遵循该格式。
C(或C ++)中typedef声明的语法基于普通声明的语法。事实上,添加typedef
关键字的语法完全相同。在这些语言中,声明不能清楚地分为两部分,正如您在案例中所做的那样。声明语法要复杂得多。声明的名称通常位于描述该名称类型的标记的中间。
对于一个简单示例,数组类型为a
的名为int [10]
的对象的声明如下所示
int a[10];
它包含名称左侧的部分(int
)和名称右侧([10]
)。类似地,在typedef声明中,描述该类型的标记可以(并且将)驻留在新类型名称的左侧和右侧。在你的例子中
typedef cell (*proc_type)(const std::vector<cell> &);
正在声明新名称proc_type
,而双方围绕它的所有内容实际上都描述了此新typedef名称所代表的类型cell (*)(const std::vector<cell> &)
。它是一个指针类型:指向函数的指针,该函数接收const std::vector<cell> &
参数并返回cell
值。
答案 1 :(得分:1)
那么typedef cell(* proc_type)是什么(const std :: vector&amp;);办?
它声明了一个名为proc_type
的新类型,它是一个指向函数的指针,该函数使用编译器的默认调用约定(通常为__cdecl
),将const std::vector<cell> &
作为输入,并返回一个cell
。
您所显示的代码之外的代码将为cell::proc
成员分配一个函数,可能是因为cell
用户以后可以在需要时调用该函数,而不知道或关心实际调用的是什么函数(在您链接的代码中,这些函数是通过add_globals()
构造函数在cell(proc_type)
中分配的。)
经典的回调场景。
答案 2 :(得分:1)
你可以通过将它们粘贴到在线cdecl网站中来推断复杂的类型定义,比如函数指针:
或者使用“左右”规则:
答案 3 :(得分:0)
typedef cell (*proc_type)(const std::vector &);
将proc_type
定义为函数指针类型cell (*)(const std::vector&)