虽然结构名称在名称空间内的结构集中必须是唯一的,但这样的名称可以是"共享"变量和函数。例如,以下代码编译得很好:
// 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的推理?我不是在询问标准中的规则。我在问这些规则背后的原因。
答案 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有没有模板。