结构名的唯一性
uniqueness of struct names
虽然结构的名称在命名空间内的结构集中必须是唯一的,但这样的名称可以与变量和函数"共享"。例如,下面的代码编译得很好:
// 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没有模板。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- vscode g++链路故障:体系结构x86_64的未定义符号
- 结构名的唯一性