Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在typedef中查找新类型_C++_C_Typedef - Fatal编程技术网

C++ 如何在typedef中查找新类型

C++ 如何在typedef中查找新类型,c++,c,typedef,C++,C,Typedef,有很多关于如何读取typedef的教程,特别是函数指针。左右规则总是以“查找新定义的类型,然后…”开头。我理解“然后…”部分,但不理解如何找到新类型 我知道这是“直觉”,但我想有一个计算机可以理解的清晰的配方 我的第一个想法:新类型是您遇到的第一个尚未定义的类型。对于函数指针为True: typedef char (*(*x[3])(int y))[5]; RETTYPE (*name[DIM]) (PARAMS) RETTYPE (* const (&(*name)(PARAMS2

有很多关于如何读取typedef的教程,特别是函数指针。左右规则总是以“查找新定义的类型,然后…”开头。我理解“然后…”部分,但不理解如何找到新类型

我知道这是“直觉”,但我想有一个计算机可以理解的清晰的配方

我的第一个想法:新类型是您遇到的第一个尚未定义的类型。对于函数指针为True:

typedef char (*(*x[3])(int y))[5];
RETTYPE (*name[DIM]) (PARAMS)
RETTYPE (* const (&(*name)(PARAMS2))[DIM])(PARAMS1)
这里,x是第一个未定义的标识符,因此x是新类型。现在,看看这个:

typedef struct { int y; } x;
typedef union { int y; } x;
typedef enum { y } x;
规则在这里不适用:y是第一个未知标识符,但x是typedefed类型


是否有规则在所有可能的typedef中查找新的typedef类型?

好吧,您的y实际上定义得很好:在前两个示例中,y是匿名结构/联合中int类型的成员变量,因此定义得很好。在第三个示例中,y是枚举成员之一,并且定义良好。为了更好地理解,假设您的typedef将被写成:

struct _x { int y; };
typedef struct _x x;

union _x { int y; }
typedef union _x x;

enum _x { y };
typedef enum _x x;
(C++允许将其简化为
typedef\ux;
但在所有三种情况下,C都不能…)


从typedef的角度来看,它是完全相同的。唯一真正的区别是,现在typedef'ed类型有名称(_x).

每种类型都存在一个非指针类型,后跟零个或多个限定符,其中限定符可以是*、&、const、volatile和/或restrict。正是在这些限定符之后,新的typename才会出现在typedef中。这将问题更改为“这些限定符出现在哪里”, 因为它们实际上不会出现在构成基类型的字符的末尾,但当基类型是数组和/或(成员)函数时,它们可能会出现在“中间”的某个位置

例如:

typedef int array[5]; // new type 'array' of type int[5].
typedef int* array[5]; // new type 'array' of type int*[5];
typedef int (*array)[5]; // new type 'array' of type pointer-to-int[5].
typedef int function(float); // new type 'function' of type int ()(float)
typedef int (*function)(float); // new type 'function' of type int (*)(float) or pointer-to int ()(float).
typedef int (Class::*member)(float); // new type 'member' of type member-function-pointer to int (Class::)(float).

这些是限定词出现在中间的唯一类型,其余的形式有:

typedef SOMETYPE<qualifiers here> newtype_here;
函数指针:

RETTYPE (*name) (PARAMS)
函数指针数组:

typedef char (*(*x[3])(int y))[5];
RETTYPE (*name[DIM]) (PARAMS)
RETTYPE (* const (&(*name)(PARAMS2))[DIM])(PARAMS1)
返回数组指针的函数:

TYPE (*name(PARAMS)) [DIM]
指向函数(1)的指针,返回对常量函数(2)指针数组的引用:

typedef char (*(*x[3])(int y))[5];
RETTYPE (*name[DIM]) (PARAMS)
RETTYPE (* const (&(*name)(PARAMS2))[DIM])(PARAMS1)
因此,如果您可以消除所有带有参数的方括号,这些参数可以通过以下事实来识别:它们以一个已知类型(即:(int…)开头,那么新类型将出现在一个或多个限定符之后的最右边或最里面的一对方括号(不是函数(PARAMS))中

让我们分步骤构造上面的类型:

指向 -函数(2)返回 -提及 -一系列 -常数 -指向 -函数(1)

现在倒读:

函数(1):

指向:

RETYPE (* )(PARAMS1)
         ^
RETTYPE (* const (& (* )(PARAMS2))[DIM])(PARAMS1)
                      ^
(being)const:

一系列:

RETTYPE (* const ( )[DIM])(PARAMS1)
                  ^
提及:

RETTYPE (* const (& )[DIM])(PARAMS1)
                   ^
函数(2)返回:

RETTYPE (* const (& ( )(PARAMS2))[DIM])(PARAMS1)
                     ^
指向以下内容的指针:

RETYPE (* )(PARAMS1)
         ^
RETTYPE (* const (& (* )(PARAMS2))[DIM])(PARAMS1)
                      ^

然后,新类型名称将放在^s指向的位置。

在后面的三个示例中,名称“y”不是“尚未定义”或“未知”——它分别由出现的结构、联合和枚举定义。(不能细分
enum{y}
)示例的结构与
typedefint x相同
。尝试“大括号外的第一个未定义标识符”。如果删除
tyoedef
关键字,剩下的就是变量声明。typedef的名称是变量的名称。我不会将此作为答案发布,因为解析变量声明仍然非常重要。顺便说一句,
typedef
并没有创建新类型,只是为现有类型创建了一个新名称。@n.m.或“不是
struct
/
union
/
enum
标记的大括号外的第一个未定义标识符”。要扩展我之前的注释,
typedef
在语法上被视为存储类说明符,像
extern
static
,或者
register
。从逻辑上讲,这是一件非常不同的事情(它为一个类型创建一个新名称,而不是声明一个对象)。语法上的相似性纯粹是为了方便,除非你用的是C语言,其中
struct\ux{inty;};类型定义x x解析为编译时错误,因为您需要
struct\ux{inty;};typedef结构x。长话短说:当心琐碎的答案。绝对正确-没有注意到问题也被标记为“C”。。。正确编辑了答案。您的答案没有引用我的问题。根据您所说的,类型说明符(加上后面的内容)引入了typedef'd类型。对于我示例中的结构,情况并非如此:
typedef struct{int y;}x:第一次完全提到类型说明符(从左到右读取)是在
int
之后(结构尚未完全定义)。因此,从您的回答来看,
y
应该是typedef'd。我说过,只有数组、函数和成员函数具有前缀和后缀(限定符和新类型显示在中间)。由于结构既不是也不是,因此新类型将显示在末尾。语法是:
typedef struct{…}newtype
{…}
之间的内容并不重要。[我是第一个(新的ABI)C++ Deangangle的作者,它正确地散列100%;)一个Deangangle输出类型;因此我非常确信,我在底部显示的一种类型的构造是正确的思考方式。尽管类型尚未完成,但在所有示例中,第一个未知标识符仍然是“array”(对应于问题中的“x”)。因此,约翰的直觉在这里也同样适用(好吧,至少,如果把这个问题理解为“找到……的名字”,这是我凭直觉所做的)。乍一看,这似乎与struct/union/enum案例(int-array int-y)相冲突,但重要的区别在于,我们在类型定义中是正确的,在考虑“第一个未知”规则之前,必须先完成该定义…@CarloWood:让我们看看我是否可以遵循: