pal*_*asb 5 c++ namespaces name-lookup type-alias
我有以下的代码定义size_t为等价的std::size_t和::size_t,如果我包括<cstddef>。
// h.hpp
namespace N {
using size_t = decltype(sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)
// a.hpp
#include <h.hpp>
namespace N {
class C {
size_t size() const;
};
void f(size_t);
}
// ^^^ These use N::size_t!
Run Code Online (Sandbox Code Playgroud)
这是否以任何方式违反C ++标准,并且会在使用这些标头和定义std::size_t和的其他标准标头的代码中引起任何错误::size_t吗?如果有人在任何情况下都无法使用std::size_t并且N::size_t可以互换,或者仅size_t在任何情况下使用都会引起歧义,我也将认为它是一个错误。
// someOtherFile.cpp
#include <a.hpp>
#include <cstdint>
namespace N {
// Can there be any problem here? (Inside N::)
}
// Or here? (Outside N::)
Run Code Online (Sandbox Code Playgroud)
我的猜测不会是因为我和标准size_t都只是类型别名unsigned long (long) int
您的别名不会引起任何问题。它出现在自己的名称空间范围内,因此别名声明不会重新声明任何内容。即使客户端代码是不负责任的,并且做一些调皮的事情,例如:
using namespace std;
using namespace N;
size_t foo;
Run Code Online (Sandbox Code Playgroud)
仍然很好,因为size_t是相同的类型,而不管别名来自哪个命名空间。仅当来自不同名称空间的相同名称引用不同的实体时,名称查找才会失败:
[namespace.udir]
6如果名称查找在两个不同的命名空间中找到名称的声明,并且声明未声明相同的实体且未声明函数,则名称的使用格式错误。
根据C ++标准的“实体”涵盖了各种各样的事物,包括类型。这就是症结所在,因为类型别名不是类型,所以它只是已经存在的类型的新名称。因此,这两个(不合格的)别名使用相同的名称。