【问题标题】:Same name in typedef and using from a namespacetypedef 中的同名并从命名空间中使用
【发布时间】:2019-04-29 04:10:10
【问题描述】:

示例代码:

struct X { void f() {} };
typedef X A;

namespace N { 
    struct A { void g() {} };
};

using N::A;

int main()
{
    A a;
    a.f();
}

此代码编译正确,A a; 创建一个X,而不是N::A

标准中的哪些规则涵盖了这种行为?我期待 A a; 会出现模棱两可的错误。如果我将第一个结构命名为 A 而不是 X 并删除 typedef,那么我确实会收到这样的错误。 (g++ 8.3)

【问题讨论】:

  • Clang 声明对 A 的引用不明确。

标签: c++ namespaces language-lawyer typedef ambiguous


【解决方案1】:

根据[namespace.udecl]/1 using N::A 将不合格的A 引入到使用声明出现的声明区域中。

... unqualified-id 在声明区域中声明,其中 using-declaration 显示为 using-declarator 引入的每个声明的同义词。

因此,[namespace.udecl]/13 共同覆盖了歧义

由于 using-declaration 是一个声明,因此对同一声明区域中同名声明的限制也适用于 using-declaration。

[basic.scope.declarative]/4

给定单个声明区域中的一组声明,每个 它指定了相同的非限定名称,

  • 应该都指同一个实体,或者都指函数和函数模板;或
  • 确切地说,一个声明应声明一个非 typedef 名称的类名或枚举名,而其他声明应全部引用相同的变量、非静态数据成员或枚举数,或全部引用函数和函数模板;在这种情况下,类名或枚举名是隐藏的。

OP 中的 typedef 声明和 using 声明不填充任一项目符号,因此同一声明区域中的这对声明格式不正确。

【讨论】:

  • using N::A; 没有指定不合格的名称,所以我不确定第二个引号如何应用? (也没有编译器报告using N::A; 的错误,尽管这可能是一个错误)
  • @M.M - using N::A 将不合格的名称 A 添加到它出现的声明性区域中。但也许是查找应该出现问题。我会仔细检查。
  • 在名称查找中未找到任何内容。所以我不确定它是否应该在引入名称或查找名称时发出诊断信息,但我确信上面的两个项目符号应该使其格式不正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多