请参阅以下代码
struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };gcc 6.1、clang3.8和msvc 2015更新3都拒绝编译,因为A不是C内部可访问的名称,因为A是B的一个私人基地。gcc认为A在using base_type = A中指的是A的默认构造函数。msvc和clang似乎不是。
编译错误可能是由于继承触发的名称注入(因为将using base_type = A修改为using base_type = ::A使所有编译器都能正常工作),但我想知道这个奇怪的错误是否是标准所说的。
更具体地说,
A::type那样,A只是一个类名(尽管gcc把它误解为一个函数名),它是引入到C而不是A或B中的。为什么这个名称被认为是B的私有名称发布于 2016-07-04 08:26:54
按照unqualified name lookup规则
(强调地雷)
对于非限定名,该名称在范围解析操作符的右侧没有出现::,名称查找检查范围如下所述,直到它找到至少一个任何类型的声明,即,此时查找停止,而没有进一步的作用域被检查。
因此,名称A将首先在基类范围内找到,此处不考虑全局命名空间中的名称。之后,执行访问权限检查,然后编译失败。
::A指定全局范围中的名称并解决这个问题,这使得它成为一个qualified name lookup。
发布于 2016-07-04 08:28:43
将我的评论作为回答(似乎更像是一个回答而不是一个评论):
我猜这是因为A的名称查找在C中是如何工作的。首先,它在使用之前检查是否在A的作用域中声明了任何名称为C。因为它找不到一个,所以它在B的范围内检查它,因为它是基类。如果它在B范围内找不到A,它将在global namespace中查找。但是,在第二次查找(即A范围内的B )时,B的私有继承就被阻止了。由于它使用fully qualified名称工作,这使我认为真正的问题必须在相同的行上。
https://stackoverflow.com/questions/38179777
复制相似问题