c++ - 没有标识符时如何读取复杂的 C++ 类型声明?

标签 c++ types syntax

有众所周知的螺旋和左右规则等,用于读取复杂的 C++ 类型,例如

int (*(*foo)(char *,double))[9][20];

Foo 是一个指针(改变方向,移出括号)

到一个函数,它接受一个指向 char 和一个 double 的指针,然后返回(再次改变方向)

指向(再次括号,改变方向)的指针

维度为 9,20 的 2d 阵列(到达右端,向左外螺旋)

整数。

但是如果没有标识符,我该如何处理这样的类型,例如在定义函数参数的类型时:
void foo(int *(*(* )(int(* )(int (* )(int))))())
                  ^       ^        ^
                  identifiers omitted

如何以直观的方式识别最里面的元素?
顺便说一句,即使 cdecl 工具在最后一个示例中也会出现语法错误,但它确实可以编译。

当然,编译器有一种明确定义的方式来解析这样的乱码。它怎么知道从哪里开始?

最佳答案

读取复杂类型的规则假定该类型已经被解析(并且您知道“最里面”的点在哪里)。由外而内的解析规则,就像在数学课上阅读复杂的表达式一样。当你打括号时,给它一个名字然后回来(除非它足够简单,可以自己处理)。免责声明:我使用文本编辑器来定位匹配的括号。 ;)

与此声明有关的另一个考虑因素是,一旦类型是函数,参数列表中的困惑就是单独的解析。比如解析void (*)(big old mess)的时候,你有一个指向函数的指针。函数的签名需要大的旧困惑,但不是为了理解你正在处理一个函数。

继续手头的例子:

void foo(int *(*(* )(int(* )(int (* )(int))))())


看完voidfoo ,你在括号里面打了一个复杂的烂摊子。给那个烂摊子起个名字。
void foo( A )

在哪里 Aint *(*(* )(int(* )(int (* )(int))))() .所以你最外层的解析是一个返回 void 的一元函数,我们还需要解析参数A .请注意,我们已经知道本文的总体目的是什么:它声明了一个名为 foo 的函数。 .其余类型没有名称,因为参数的名称是可选的。
A: int *( B )()

在哪里 B*(* )(int(* )(int (* )(int))) .所以参数为foo是其最外层类型为返回指向 int 的指针的空函数。 .想必我们会发现“某物”是一个指针,但我们还是需要解析B确认。 (好的,向前略过一点,看到 B 以星号开头。它是指向这个空函数的指针。)
B: *(* )( C )

在哪里 Cint(* )(int (* )(int)) .这是一个指向一元函数的指针,它的参数是某种复杂类型,它的返回值是一个指向我们之前解析的指针(空函数)。与最初的解析一样,我们发现了另一个开始阅读的地方,因为困惑已被插入参数列表。 foo 的参数是一个指向一元函数的指针,它的参数是某种复杂类型,它的返回值是一个指向一个空函数的指针,它返回一个指向 int 的指针.
C: int(* )( D )

在哪里 Dint (* )(int) .再一次,困惑已经进入了参数列表。这个级别的东西是一个指向返回 int 的一元函数的指针。 .
D: int (* )(int)

最后,简单性:指向接受 int 的一元函数的指针。并返回 int .

所以....

这声明 foo成为返回 void 的一元函数其参数是指向一元函数的指针,返回指向空函数的指针,返回指向 int 的指针,其参数是指向返回 int 的一元函数的指针其参数是指向返回 int 的一元函数的指针其参数为int .

英文版的代码和代码一样容易理解,不是吗? :) 让我们尝试一些更有条理的东西。
  • foo
  • 返回:void
  • 参数:指向函数的指针
  • 返回:指向函数的指针
  • 返回:指向 int 的指针
  • 参数:指向函数的指针
  • 返回:int
  • 参数:指向函数的指针
  • 返回:int
  • 参数:int

  • 唷。 children ,不要在家里这样做。给你的中间类型命名,让程序员免去一些痛苦。

    关于c++ - 没有标识符时如何读取复杂的 C++ 类型声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62182309/

    相关文章:

    types - 是否可以在 Common Lisp 中定义递归类型?

    c++ - 如何在同一类的公共(public)函数中调用私有(private)类函数(带参数)?

    c++ - 使用转换函数直接初始化

    c++ - 如何使用 C 或 C++ 编程改变 USB 上的电压并检测 USB 上的变化电压

    c++ - 分配给 int 类型缓冲区的大内存大小

    c# - 在没有枚举的情况下在 C# 中实现自己的数据类型?

    c - 如何用逗号 (,) 分隔两个 C 语句?

    c++ - 这是 Objective-C 代码文件中的 C++ 吗?

    c++ - 试图创建一个复制构造函数,我该如何解决这个问题?

    C++ 值初始化 vector 迭代器比较