结构名的唯一性

uniqueness of struct names

本文关键字:唯一性 结构      更新时间:2023-10-16

虽然结构的名称在命名空间内的结构集中必须是唯一的,但这样的名称可以与变量和函数"共享"。例如,下面的代码编译得很好:

// Code 1
struct h{};
int h{ 8 };
同样,在: 中也没有碰撞。
// Code 2
struct h{};
void h(){}

1)允许名称共享的理由是什么?

此外,如果我们将模板加入到混合中,我们会遇到一些奇怪的情况。代码

// Code 3
template< class H > void h(){}
struct h{};
template< class H > struct j{};
void j(){}

编译;但是下面的代码失败了:

// Code 4
struct h{};
template< class H > void h(){}
void j(){}
template< class H > struct j{};

2)为什么允许代码2的推理不够好,不能允许代码4?我不是在问标准中的规则。

1)允许名称共享的理由是什么?

根据Bjarne Stroustrup的"c++的设计和演变",章节2.8.2"结构标签vs.类型名称",引入该特性是为了保持与C语言的兼容性。C语言需要使用struct关键字来命名结构(命名类型定义不需要关键字)。然后,您可以使用相同的标识符来声明结构体、函数或变量:

struct X { int m; };
void X(void);
X(); // call X
struct X x; // create a new object of type X

对用户有利的显著语法简化是在c++中引入的代价是给实现者带来了一些额外的工作一些C兼容性问题。[…在带有类的C语言环境中[dyp: c++的前身],这已经困扰了我一段时间因为它使用户定义类型成为二等公民语法。

[…]

解决这个特殊问题的真正需要来自这样一个事实,即一些标准UNIX头文件,特别是stat.h,依赖于struct和具有相同名称的变量或函数。

D&E 2.8.2


2)为什么允许代码2的推理不够好,不能允许代码4?

我先引用c++ 11标准:

类模板不能与其他模板同名,类、函数、变量、枚举、枚举器、命名空间或类型在相同的作用域(3.3)中,除非在(14.5.5 [dyp: class template partial specialization]中指定)。除了函数模板可以通过(非模板)具有相同名称的函数或由其他函数模板使用相同的名称(14.8.3 [dyp:这是指重载]),在命名空间作用域中声明的模板名称类范围在该范围内是唯一的。

c++ 11国际标准[temp]p5

根据我对这段话的解释,代码3和4都是非法的。clang++拒绝它们,但接受代码3的第一部分:

template< class H > void h(){}
struct h{};

根据[temp]p5,这也应该是非法的。

考虑到所有这些例子(3、4和3的开头)都是非法的,我认为的理由是在这些情况下你不需要兼容性异常:C没有模板。