0

当我看到这条线时,我正在看这篇文章。

简而言之,代码如下所示:

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 &); 做?
typedef 应该像这样使用

typedef (existing) (new)

那么,当我们可以使用 cell 代替时,为什么要声明如此复杂的新类型呢?

4

4 回答 4

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,而两侧围绕它的所有内容实际上都描述了cell (*)(const std::vector<cell> &)这个新的 typedef 名称将代表的类型。它是一个指针类型:一个指向接收const std::vector<cell> &参数并返回cell值的函数的指针。

于 2013-10-11T01:19:59.053 回答
1

那么 typedef cell (*proc_type)(const std::vector &); 做?

它声明了一个名为的新类型proc_type,它是一个指向使用编译器默认调用约定(通常为__cdecl)的函数的指针,将 aconst std::vector<cell> &作为输入,并返回 a cell

然后,您显示的代码之外的代码将为cell::proc成员分配一个函数,大概是这样cell用户以后可以在需要时调用该函数,而不知道或关心实际调用的是什么函数(在您链接到的代码中,这些函数被分配通过构造函数)add_globals()cell(proc_type)

一个经典的回调场景。

于 2013-10-11T01:00:23.413 回答
1

您可以通过将它们粘贴到在线 cdecl 网站来推断复杂的 typedef,例如函数指针:

http://cdecl.org

或者通过使用“左右”规则:

http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

于 2013-10-11T04:38:44.273 回答
0

typedef cell (*proc_type)(const std::vector &);

定义proc_type为函数指针类型cell (*)(const std::vector&)

于 2013-10-11T01:00:07.527 回答