please see the following code
请参见下面的代码
struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
All of gcc 6.1, clang 3.8, and msvc 2015 update 3 refuse to compile this, as A
is not an accessible name inside C
since A
is a private base of B
. It seems that gcc thinks A
in using base_type = A
refers to the default constructor of A
. msvc and clang seem not.
3.8 gcc 6.1,叮当声,msvc 2015更新3拒绝编译这个,不是一个可访问的名称在C b是一个私人基地以来似乎gcc认为在使用base_type =指A . msvc的默认构造函数和叮当声似乎不是。
Perhaps the compilation error is due to the injection of names triggered by inheritances (because modifying using base_type = A
into using base_type = ::A
make all the compilers work fine), but I want to know if this weird error is what the standard says.
也许编译错误是由于继承触发的名称注入(因为使用base_type = A修改为使用base_type =:A使所有编译器工作正常),但是我想知道这个奇怪的错误是否是标准所说的。
More concretely,
更具体地说,
- As I understood, not like
A::type
,A
is just a class name (although gcc misinterprets it as a function name) which is introduced toC
not insideA
norB
. Why this name is considered private toB
? - 正如我所理解的,不像A::type, A只是一个类名(尽管gcc错误地将其解释为函数名),它被引入到C中,而不是在A或B中。
- Should this compilation error be considered a bug, or is an edge case of the specifications of the standard?
- 这个编译错误应该被认为是一个bug,还是标准规范的边缘情况?
2 个解决方案
#1
28
According to the rule of unqualified name lookup:
根据不合格名称查找规则:
(emphasis mine)
(强调我的)
For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
对于一个不合格的名字,这个名字似乎并不正确的范围解析操作符::,名字查找检查范围如下所述,直到找到至少一个声明任何形式的,在这段时间里查找了,没有进一步检查范围。
So the name A
will be found firstly at the base class scope, the name in the global namespace won't be considered here. After that, access right checking is performed and then compile failed.
因此,将首先在基类范围内找到名称A,在这里不考虑全局名称空间中的名称。然后,执行访问权检查,然后编译失败。
And ::A
specifies the name in global scope and solves the issue, which making it a qualified name lookup.
和::A在全局作用域中指定名称并解决问题,这使它成为一个限定名称查找。
#2
2
Posting my comment as answer (seems like an answer more than a comment):
发布我的评论作为回答(看起来更像是回答而不是评论):
I am guessing this is due to how name lookup for A
inside C
works. First it checks to find if anything is declared with a name A
in the scope of C
before using. Since it does not find one, it is checking it in the scope of B
since it's the Base class. And in case it does not find A in Bs scope, it will look out in the global namespace
. But somehow the private inheritance of A
by B
is getting stopped at the second lookup i.e inside the scope of B
. Since it works using fully qualified
name, that makes me think that the real issue must be on the same lines.
我猜想这是由于Ainside C的名称查找是如何工作的。首先,它检查是否在使用前在C的范围内使用名称a声明了任何内容。因为它没有找到一个,所以它在B的范围内检查,因为它是基类。如果它没有在Bs范围中找到A,它将在全局命名空间中查找。但是不知何故,A by B的私有继承在第二次查找i时就停止了。e在b的范围内,因为它使用完全限定的名称,所以我认为真正的问题必须在同一条线上。
#1
28
According to the rule of unqualified name lookup:
根据不合格名称查找规则:
(emphasis mine)
(强调我的)
For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
对于一个不合格的名字,这个名字似乎并不正确的范围解析操作符::,名字查找检查范围如下所述,直到找到至少一个声明任何形式的,在这段时间里查找了,没有进一步检查范围。
So the name A
will be found firstly at the base class scope, the name in the global namespace won't be considered here. After that, access right checking is performed and then compile failed.
因此,将首先在基类范围内找到名称A,在这里不考虑全局名称空间中的名称。然后,执行访问权检查,然后编译失败。
And ::A
specifies the name in global scope and solves the issue, which making it a qualified name lookup.
和::A在全局作用域中指定名称并解决问题,这使它成为一个限定名称查找。
#2
2
Posting my comment as answer (seems like an answer more than a comment):
发布我的评论作为回答(看起来更像是回答而不是评论):
I am guessing this is due to how name lookup for A
inside C
works. First it checks to find if anything is declared with a name A
in the scope of C
before using. Since it does not find one, it is checking it in the scope of B
since it's the Base class. And in case it does not find A in Bs scope, it will look out in the global namespace
. But somehow the private inheritance of A
by B
is getting stopped at the second lookup i.e inside the scope of B
. Since it works using fully qualified
name, that makes me think that the real issue must be on the same lines.
我猜想这是由于Ainside C的名称查找是如何工作的。首先,它检查是否在使用前在C的范围内使用名称a声明了任何内容。因为它没有找到一个,所以它在B的范围内检查,因为它是基类。如果它没有在Bs范围中找到A,它将在全局命名空间中查找。但是不知何故,A by B的私有继承在第二次查找i时就停止了。e在b的范围内,因为它使用完全限定的名称,所以我认为真正的问题必须在同一条线上。