【发布时间】:2016-11-05 21:27:51
【问题描述】:
请看下面的代码
struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
所有 gcc 6.1、clang 3.8 和 msvc 2015 更新 3 都拒绝编译它,因为 A 不是 C 内的可访问名称,因为 A 是 B 的私有基础。看来gcc认为using base_type = A中的A指的是A的默认构造函数。 msvc 和 clang 似乎没有。
也许编译错误是由于继承触发的名称注入(因为将using base_type = A修改为using base_type = ::A使所有编译器都可以正常工作),但我想知道这个奇怪的错误是否是标准所说的。
更具体地说,
- 据我了解,不像
A::type,A只是一个类名(尽管 gcc 将其误解为函数名),它被引入到C不在里面A也不是B。为什么此名称被视为B的私有名称? - 应将此编译错误视为错误,还是标准规范的边缘情况?
【问题讨论】:
-
我猜这是因为
A在C中的名称查找是如何工作的。首先,它检查是否在C的范围内,在using之前声明了名称为A的任何内容。因为它没有找到一个,所以它在B的范围内检查它,因为它是基类。如果在Bs 范围内找不到A,它会在global namespace中查找。但不知何故,B的A的private inheritance在第二次查找时停止,即在B的范围内。由于它使用fully qualified名称工作,这让我认为真正的问题必须在同一行。 -
@PiotrSkotnicki 谢谢,它直接回答了这个问题。但是,你能告诉我这条规则背后的理由吗?
-
@PiotrSkotnicki 好吧,没关系。我想我对事情有些了解。谢谢!
标签: c++ c++11 name-lookup using-declaration private-inheritance