【问题标题】:Why is it forbidden to qualify name in extern declaration?为什么禁止在外部声明中限定名称?
【发布时间】:2019-11-07 13:04:52
【问题描述】:

为什么外部声明引入的名称只允许来自最内层的封闭命名空间?如果不是,它会引起什么并发症?还是只是因为这部分标准是从 C 标准中复制而来的,没有命名空间?

Please see the respective part of the standard

编辑: 一个可以方便地进行限定的示例场景:在命名空间 ns 中的函数模板 f 中使用 x,其中 x 定义在全局命名空间中的某处,不希望引入(在函数之外定义)在所有#include标头带有f的翻译单元中。

namespace ns
{
  template <typename> void f()
  {
    // extern int ::x; // ill-formed
    extern int x;      // refers to ns::x, which is not the case :(
    ++x;
  }
}

【问题讨论】:

  • 引用的段落没有说明任何名称的限定。它只在两个声明声明同一个实体时才说。
  • @n.'pronouns'm.: 忽略在最里面的封闭命名空间范围之外声明的实体;这个(不完整的)声明明确禁止使用这个声明链接到所述命名空间之外的任何名称。也许资格本身在标准的其他地方被明确禁止 - 我不知道。但也许它仅被这条规则暗示。

标签: c++ namespaces extern


【解决方案1】:

为什么禁止在 extern 声明中限定名称?

因为它没有意义。

假设您想在命名空间foo:::baz 中使用foo::bar。有两种情况

  1. foo::bar 的声明可见。那么你不需要重新声明它。只需使用名称,如果需要,请限定。
  2. foo::bar 的声明不可见。那么你不能首先在foo 以外的任何命名空间中声明它。

为什么外部声明引入的名称只允许来自最内层的封闭命名空间?

他们不是。它们可能来自全局命名空间,这是extern 的主要用例。另一个用例是前向声明一个稍后将在同一命名空间中定义的函数,我想这是允许此类相同命名空间声明的唯一原因。除了这些用例之外,对extern 的需求并不大。从内部 foo::baz 前向声明 foo::bar 太混乱且容易出错。

【讨论】:

  • 您能看一下我添加到问题中的示例吗?它介绍了您的答案中未涵盖的用例。谢谢
  • 不知道,也许标准不鼓励你使用全局变量。
猜你喜欢
  • 2012-02-17
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多