结构名称的唯一性

Hec*_*tor 6 c++ language-lawyer c++11

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

// Code 1
struct h{};
int h{ 8 };
Run Code Online (Sandbox Code Playgroud)

同样,没有碰撞:

// Code 2
struct h{};
void h(){}
Run Code Online (Sandbox Code Playgroud)

1)允许该名称共享的原因是什么?

而且,如果我们将模板放入混合中,我们会遇到一些奇怪的情况.代码

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

编译; 但以下代码失败:

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

2)为什么允许代码2不足以允许代码4的推理?我不是在询问标准中的规则.我在问这些规则背后的原因.

dyp*_*dyp 3

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

根据Bjarne Stroustrup 所著的《The Design and Evolution of C++》第 2.8.2 节“结构标记与类型名称”,引入此功能是为了保持与 C 的兼容性。C 语言需要使用关键字struct来命名结构(不需要关键字来命名 typedef)。然后,您可以使用相同的标识符来声明结构以及函数或变量:

struct X { int m; };
void X(void);

X(); // call X
struct X x; // create a new object of type X
Run Code Online (Sandbox Code Playgroud)

为了用户的利益,C++ 中引入了显着的语法简化,但代价是实现者需要做一些额外的工作以及一些 C 兼容性问题。[...] 在带有类的 C 上下文中 [dyp:C++ 的前身],这让我烦恼了一段时间,因为它在语法上使用户定义类型成为二等公民。

[...]

解决这个特定问题的真正需要来自于以下事实:某些标准 UNIX 头文件(尤其是 )stat.h依赖于 astruct和具有相同名称的变量或函数。

——D &E 2.8.2


2) 为什么允许代码 2 的推理不足以允许代码 4?

我首先引用C++11标准:

类模板不得与同一范围 (3.3) 中的任何其他模板、类、函数、变量、枚举、枚举器、命名空间或类型具有相同的名称,除非 (14.5.5 [ dyp: 类模板部分专业化])。除了函数模板可以由具有相同名称的(非模板)函数或其他具有相同名称的函数模板重载(14.8.3 [dyp:这指的是重载])之外,在命名空间范围中声明的模板名称或在类范围内应在该范围内是唯一的。

-- C++11 国际标准 [temp]p5

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

template< class H > void h(){}
struct h{};
Run Code Online (Sandbox Code Playgroud)

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

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