在我自己的名称空间中定义size_t会造成歧义或其他错误吗?

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

Sto*_*ica 6

您的别名不会引起任何问题。它出现在自己的名称空间范围内,因此别名声明不会重新声明任何内容。即使客户端代码是不负责任的,并且做一些调皮的事情,例如:

using namespace std;
using namespace N;

size_t foo;
Run Code Online (Sandbox Code Playgroud)

仍然很好,因为size_t是相同的类型,而不管别名来自哪个命名空间。仅当来自不同名称空间的相同名称引用不同的实体时,名称查找才会失败:

[namespace.udir]

6如果名称查找在两个不同的命名空间中找到名称的声明,并且声明未声明相同的实体且未声明函数,则名称的使用格式错误。

根据C ++标准的“实体”涵盖了各种各样的事物,包括类型。这就是症结所在,因为类型别名不是类型,所以它只是已经存在的类型的新名称。因此,这两个(不合格的)别名使用相同的名称。