如何消除名称相同的名称空间和类的歧义
how to disambiguate namespace and class with identical names
考虑以下代码:
struct foo {
typedef int bar;
};
namespace foo {
class baz {
/* code */
};
}
这是分布在我必须处理的代码库中,它有时会起作用,我不明白是怎么回事。
只要名称空间和类不出现在同一源(预处理后),它将工作(我理解这部分)。但是,如果突然命名空间和类都被预处理器拖到同一个编译单元中,它(可能)会发生冲突(我不知道这种情况是否发生在源代码中)。
是否有一个约定,允许编译器总是正确地解析代码结构?最合乎逻辑的做法是禁止名称空间和类使用相同的符号。应用的编码风格允许名称空间与类冲突,尽管存在歧义,因此我更喜欢一种方法来告诉编译器使用情况,而不是改变编码约定。
类似:
use_namespace(foo)::baz b;
use_class(foo) b;
c++ 11标准第7.3.1/2段禁止:
original-namespace-definition 中的标识符不能在声明性中先前定义过原始命名空间定义出现的区域。原始名称空间定义中的标识符命名空间的名称。随后,在该声明性区域中,它被视为原始命名空间。
关于你方的声明:
只要命名空间和类不在同一个源中(预处理后),它就可以工作
这是不正确的。第7.3.2/4段(特别是最后一句)告诉你为什么看起来在"工作",尽管你的程序是病态的:
名称空间-name或名称空间-alias不得声明为同一名称中任何其他实体的名称声明区域。在全局作用域中定义的命名空间名称不能声明为任何程序全局范围内的其他实体。不需要诊断违反此规则.
这意味着你正在处理的代码库有未定义的行为,这是一个潜在的定时炸弹,可能会以不可理解的方式爆炸。
只要命名空间和类不出现在同一个源中(预处理之后),它就会工作(我理解这部分)。
不,它没有。根据c++ 11 3.3.4/4:
,为两个不同的实体声明相同的名称会产生未定义的行为给定一个声明区域中的一组声明,每个声明都指定了相同的非限定名,它们应该都指向同一个实体
(有一些例外,不包括为类和命名空间赋予相同的名称)。
由于声明在单独的翻译单元中,许多编译器无法诊断错误,因此它可能看起来有效。
但是,如果突然命名空间和类都被预处理器拖到同一个编译单元中,它(可能)会发生冲突(我不知道这种情况是否发生在源代码中)。
既然它们在同一个翻译单元中,就可以诊断错误了
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 在命名空间中定义函数还是限定函数
- 构造对象的歧义
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- OpenGL相机和相机空间转型的困惑
- CUDA内核和数学函数的显式命名空间
- 打印第二列时的2d字符矢量打印空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何在不同命名空间中与候选人拨打ADL的歧义
- 与类和命名空间一起使用 差异/歧义
- 如何消除名称相同的名称空间和类的歧义