这是我对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
在常规namspace中找到,并且该名称恰好是typedef
名称,因此它可以是有效的类型说明符。第二个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名称冲突。
如果添加标记,然后将两者struct myStruct
并myStruct
单独将引用类型,在C和C ++:
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)的主题,则该程序为格式错误。—尾注]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句