我目前对“使用(命名空间)”语句在C ++中的工作方式感到困惑。
我有:
//somewhere in included headers
typedef unsigned int uint;
namespace mine {
typedef unsigned int uint;
}
namespace other {
using namespace mine;
void foobar () {
uint offender = i;
}
}
结果(转述):
对'uint'的引用含糊不清。
候选人是
typedef unsigned int uint
和
typedef unsigned int mine :: uint
同时,当我做的时候
namespace other {
using namespace mine;
using mine::uint;
void foobar () {
uint offender = i;
}
}
一切正常。 我觉得“使用标识符;”似乎很奇怪更改其他typedef定义的可见性(隐藏全局定义?)。 有人能指出我用C ++中的哪种规则管理跨命名空间的typedef解析?
答案 0 :(得分:11)
using-directive 可见的名称出现在最近的封闭范围内,该范围包含[ - 直接或间接 - ] using-directive 和指定的命名空间。 (7.3.4 [namespace.udir])
这意味着当在uint
中的 using-directive 之后查找时,other
声明在全局命名空间范围内出现。
using-declaration 与任何其他声明一样,在其出现的范围内声明一个名称。这就是为什么在第二个示例中,using mine::uint;
隐藏uint
引入的using namespace mine;
,因为后者似乎来自全球范围。
答案 1 :(得分:4)
您的原始代码会混淆编译器,因为uint可能是
::uint
或
::mine::uint
因此编译器会向您抛出该错误消息。在“修复”中,使用mine::uint
明确指定::mine::uint
应该是首选。
但是,IMO应避免typedef
冲突。它使代码难以维护。
答案 2 :(得分:1)
我不能为你引用章节和经文,但这对我有意义。如果编译器在当前命名空间中找不到符号uint
,它会查找其他命名空间以查看它是否可以在那里找到符号。因为它在另外两个命名空间中找到它,所以它是不明确的。
当您说using mine::uint
时,您已将该符号导入当前块,因此在需要检查其他命名空间之前找到它。
答案 3 :(得分:0)
它并不掩盖全球性的。这就是你有歧义的原因。