![](/img/trans.png)
[英]Why can a typedef-name for a struct not be used interchangeably with the struct name?
[英]Typedef-name conflicts with struct tag in C++
这是我对C ++中的结构声明的第二次调查。 (第一个在这里 )但是现在我遇到了这个帖子 。 具体来说,我不确定为什么这在C语言中完全可以,但在C ++中不是很好。
typedef struct{
int one;
int two;
}myStruct;
struct myStruct; //forward declaration fails
void blah(myStruct* pStruct);
上面的代码在我的带有GCC的Ubuntu机器上可以正常编译。 我之所以这样是因为第一个myStruct
位于函数,变量名所在的普通命名空间中。 第二个myStruct
位于Tag命名空间中。 当编译器在函数原型中看到myStruct*
时,它将在两个名称空间中进行搜索,并在常规命名空间中找到myStruct
,并且该名称恰好是typedef
名称,因此它可以是有效的类型说明符。 myStruct
可以将第二个myStruct
定义为程序员想要的东西。 与第一个未命名的 myStruct
不会有任何混淆/冲突,因为程序员必须使用struct myStruct
来引用第二个。
但是在C ++中,根据链接的问题中的讨论,我的理解是,第一个typedef myStruct
像往常一样位于正常的名称空间中。 第二个myStruct
也位于常规名称空间中(在C ++中没有特定的标记名称空间?),但可能会被其他标识符遮盖。 所以我的问题是,为什么不第一myStruct
这是在相同的命名空间第二myStruct
阴影第二myStruct
?
从更一般的意义上讲,除了程序员使用C ++语言提供的命名空间功能引入的显式命名空间外,还有任何预定义的命名空间会消除标识符(包括标签,标签,typedef名称,对象/函数标识符)的使用。像在C中一样? (在我的第一次调查中,C有4个预定义的名称空间)。 我可以在C ++标准中找到这些名称所属的地方吗?
编辑 :看来我没有把问题弄清楚。 我只想知道的是
1)标签,typedef名称,struct / union / enum的标记名称,常规函数,常规变量/对象名称属于哪些名称空间(如果在语言中定义了此类名称)? (如果我错过任何其他名称,请添加。)
2)为什么普通的函数名,普通的变量名会遮蔽标签名,而标签名却不能。
3)如果C ++中有任何子句像C中那样指定名称空间( 第6.2.1节 )
在C ++中,你不能用struct myStruct
指一个无标签结构一直typedef
版。 而且您不能定义其他struct myStruct
,因为该名称与typedef名称冲突。
如果添加标签,则在C和C ++中, struct myStruct
和myStruct
都将单独引用该类型:
typedef struct myStruct {
int one;
int two;
} myStruct;
在C ++中,这里没有冲突,因为名称只解析为一种类型,这是特殊规则特别允许的。 C ++标准的7.1.3节包含以下规则:
在给定的非类作用域中,可以使用
typedef
说明符来重新定义在该作用域中声明的任何类型的名称,以引用其已引用的类型。如果使用typedef规范在给定范围内重新定义可以使用精化类型说明符引用的实体,则该实体可以继续由精化类型说明符引用或作为枚举或枚举中的类名进行引用或类定义。
在给定范围内,不得使用typedef说明符来重新定义在该范围内声明的任何类型的名称,以引用不同的类型。
类似地,在给定范围内,不得使用与在该范围内声明的类型定义名称相同的名称声明类或枚举,并且该类型定义枚举所引用的类型不是该类或枚举本身。
[注意:命名类类型或cv限定版本的typedef名称也是类名称(9.1)。 如果使用typedef-name标识详细类型说明符 (7.1.6.3),类定义(第9条),构造函数声明(12.1)或析构函数声明(12.4)的主题,则该程序为格式错误 。 —尾注]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.