结构名称的唯一性

时间:2015-07-27 10:58:58

标签: c++ c++11 language-lawyer

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

// 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 个答案:

答案 0 :(得分:3)

  

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

根据"The Design and Evolution of C++", by Bjarne Stroustrup,第2.8.2节&#34;结构标签与类型名称&#34;,引入此功能是为了保持与C的兼容性.C语言需要使用{{1用于命名结构的关键字(命名typedef不需要关键字)。然后,您可以使用相同的标识符来声明结构以及函数或变量:

struct
  

为用户的利益进行了重要的语法简化   以实现者的一些额外工作为代价引入C ++   一些C兼容性问题。 [...]在C with Classes的上下文中   [dyp:C ++的前身],这让我生气了一段时间   因为它使用户定义的类型成为二等公民   语法。

     

[...]

     

解决这一特定问题的真正需要来自于一些标准UNIX头文件,特别是struct X { int m; }; void X(void); X(); // call X struct X x; // create a new object of type X ,依赖于stat.h以及具有相同名称的变量或函数。

     

- D&amp; 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的第一部分:

struct

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

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