【问题标题】:Is `using namespace std::placeholders;` non-conformant?`using namespace std::placeholders;` 不符合标准吗?
【发布时间】:2015-01-12 14:00:48
【问题描述】:

从第 2.10.3.2 节开始:

以下划线开头的每个标识符都保留给实现,用作全局命名空间中的名称。

考虑到这一点,这个程序标准是否符合?因为它使 _1 等可以从全局命名空间中使用?还是因为std::placeholders 被认为是“实施”而可以?还是因为_1 实际上不在全局命名空间中,所以可以吗?还有什么?

using namespace std::placeholders;
int main(){}

【问题讨论】:

  • 据我了解,它被保留意味着全局命名空间中的任何“_1”都必须来自“实现”,而标准库是“实现”的一部分。跨度>

标签: c++ language-lawyer


【解决方案1】:

我认为这个程序很好。严格来说,using-directive 不会将任何名称放入命名空间 - 它使名称可以通过名称查找访问,但实际上并不使它们成为包含 using-directive 的命名空间的成员。

引用 C++11、7.3.4:

2 using-directive 指定指定命名空间中的名称可以在 using-directive 出现在 using-directive 之后。 在非限定名称查找 (3.4.1) 期间,名称出现 好像它们是在最近的封闭命名空间中声明的,其中包含 using-directive 和 命名空间。 [ 注意: 在此上下文中,“包含”是指“直接或间接包含”。 ——结束 注意 ]

3 using-directive 不会将任何成员添加到它出现的声明区域。 ...

请注意“可以使用”、“好像它们已被声明”等语言。没有提及实际将 name 成员设置为不同的命名空间。

至于通过限定名进行访问,3.4.3.2(命名空间的限定名查找)说:

2 对于命名空间 X 和名称 m,命名空间限定的查找集 S(X,m) 定义如下: S'(X,m)X 中所有m 声明的集合和X (7.3.1) 的内联命名空间集合。如果 S'(X,m) 不是 为空,S(X,m)S'(X,m); 否则,S(X,m)S(Ni,m) 为所有命名空间 Ni 提名 通过X 中的using-directives 及其内联命名空间集。

即,使用指令的单独规则也是如此。

我会由此得出结论,using 指令不会使任何名称成为命名空间的成员,因此不会触发 _ 全局命名空间规则并且不会发生未定义行为。

【讨论】:

  • 这也是我最初的回答,除了我发布了一个我预计会失败但没有失败的程序。您的报价解释了非限定名称查找将如何成功,但限定名称查找也成功。它比您的答案中的内容更多。我也在尝试找到标准的其余相关部分。
  • 但是,如果我是编译器编写者,并且出于某种原因将_1 用作我的实现的一部分并将其放入全局命名空间中,允许(?),它会被using namespace std;?如果是这样,那会破坏我的实现吗?
  • @hvd 我也在处理合格的查找,现在发布。
  • @OmnipotentEntity 作为一个负责任的编译器编写者,如果可能出现任何混淆,您应该始终完全限定所有内容。这意味着当您的意思是特定于实现的 _1 符号时,您总是会写 ::_1,并且根据 3.4.3.2/2,查找合格命名空间的实际成员会禁用 using-directive 查找。所以你会没事的。
  • 谢谢!这正是我需要知道的。
猜你喜欢
  • 1970-01-01
  • 2016-02-27
  • 2011-10-14
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
  • 2022-07-05
相关资源
最近更新 更多