使用声明的奇怪行为

Jun*_*eon 26 c++ using-declaration private-inheritance name-lookup c++11

请参阅以下代码

struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
Run Code Online (Sandbox Code Playgroud)

所有的gcc 6.1,clang 3.8和msvc 2015更新3都拒绝编译它,因为A它不是一个可访问的名称,C因为它A是一个私有基础B.似乎gcc认为Ausing base_type = A指默认构造函数A.msvc和clang似乎没有.

也许编译错误是由于继承触发的名称注入(因为修改using base_type = Ausing base_type = ::A使所有编译器工作正常),但我想知道这个奇怪的错误是否是标准所说的.

更具体地说,

  1. 据我所知,不是A::type,A只是一个类名(虽然gcc误解为一个函数名),它不是引入C 内部 A也不引入B.为什么这个名字被认为是私人的B
  2. 该编译错误是否应被视为错误,或者是标准规范的边缘情况?

son*_*yao 28

根据不合格的名称查找规则:

(强调我的)

对于非限定名称,即名称不在范围解析运算符::右侧的名称,名称查找检查范围如下所述,直到它找到任何类型的至少一个声明,此时查找停止并且不会审查其他范围.

因此,名称A将首先在基类范围内找到,此处不会考虑全局命名空间中的名称.之后,执行访问权限检查,然后编译失败.

::A指定全局范围内的名称并解决问题,使其成为合格的名称查找.