【问题标题】:Using declaration for inner types [duplicate]使用内部类型的声明[重复]
【发布时间】:2015-10-19 11:01:15
【问题描述】:

为什么只允许对类成员使用声明作为成员声明?我做不到

struct Outer
{
    typedef int Inner;
};

void f()
{
// this doesn't work with C++14
     using Outer::Inner;
}

,但我认为这与 using-declaratives 将在其他地方声明的名称引入当前区域的预期语义相当正交。它受到 C++ 标准的明确限制

7.3.3/8:类成员的使用声明应为 成员声明

,但我想知道为什么。

我认为如果允许内部类型(typedef、类等)并定义为与

// using Outer::Inner should be identical to
using Inner = Outer::Inner

,这与命名空间的行为相同。

我知道这个问题has been asked before,但公认的答案是禁止的,因为标准是这样说的。我想知道它背后是否有任何技术原因。在其中一个 cmets 中,据说

使标准(以及所有编译器)变得更复杂 处理一个不寻常的案例,它有一个方便的解决方法 通过成本效益测试。

我会说这是一种观点,而不是争论。更改它以使语言变得更加统一是一个巨大的好处。现在,你必须教不同的东西来做同样的事情。如果您删除该子句,标准会变得更简单,这既是因为大小减小了,也是因为删除了(非常随意的)特殊情况。

更准确地说,我正在寻找技术原因为什么不允许这样做,例如它会产生歧义或其他问题。

【问题讨论】:

  • 这也在接受的答案中。引用:Making the Standard (and therefore all compilers) more complicated to handle an unusual case that has a convenient workaround just doesn't pass the cost-benefit test.
  • @user2079303 我已经用我的论点扩展了答案,为什么不是这样。
  • 我看不到您要查找的内容尚未包含在该答案中。我作为一个骗子关闭。如果你真的想要,可以悬赏以获取更多细节,但你不会得到任何东西。
  • 如果您强烈认为ISO工作组的“意见”不足以实际使用,请提交修改建议。
  • @LightnessRacesinOrbit 正如问题中所说,我正在寻找技术原因。该标准没有给出任何内容,我也不知道有任何内容,但可能存在导致问题或模棱两可的原因。通常有一些。我明确提到了这个问题,但它并没有回答我的问题,因为它没有给出超出该子句存在的任何理由。

标签: c++


【解决方案1】:

不要混淆使用声明和别名声明。 using A = B; 是一个 alias-declaration,语义上与 typedef 相同:

一个 类型定义名称 也可以由一个引入 别名声明 .这 标识符 遵循 使用 关键词 变成一个 类型定义名称 和可选的 属性说明符序列 遵循 标识符 与此有关 类型定义名称 .它具有相同的语义,就好像它是由 类型定义 说明符。特别是,它 没有定义一个新的类型,它不会出现在 类型标识 .

所以,您写using Inner = Outer::Inner,因为它与typedef Outer::Inner Inner 相同,而不仅仅是typedef Outer::Inneralias-declaration 为类型名称创建别名。

另一方面,using-declaration 有所不同:它将名称引入范围 (7.3.3/1),但它也被单词 using 调用,这有点令人困惑。

所以,

// 使用 Outer::Inner 应该等同于 使用 Inner = Outer::Inner

它们不可能相同,它们是不同的东西。

【讨论】:

  • 我指的是使用声明,例如using namespace std::chrono::miliseconds,将名称导入当前范围。现在,我希望能够对using Inner::Outer 做同样的事情,这在成员声明中是可能的,但在范围块中是不可能的。我想知道为什么,因为我没有看到这样做的原因。别名声明将是预期的语义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多