Date: Tue, 12 May 2026 14:22:29 +0000
On Tuesday, May 12th, 2026 at 5:17 PM, Ell via Std-Discussion <std-discussion_at_[hidden]> wrote:
> On Tuesday, May 12th, 2026 at 4:56 PM, Yongwei Wu <wuyongwei_at_[hidden]> wrote:
>
> > On Tue, 12 May 2026 at 21:46, Ell <ell.ell.se_at_[hidden]> wrote:
> > >
> > > On Tuesday, May 12th, 2026 at 2:49 PM, Yongwei Wu via Std-Discussion <std-discussion_at_[hidden]> wrote:
> > >
> > > > Actually, if we change
> > > >
> > > > struct Derived : public Middle { public: using ::Base::member; };
> > > >
> > > > to
> > > >
> > > > struct Derived : public Middle { public: using Base::member; };
> > > >
> > > > Clang will reject the code. So it seems to me that Clang is applying different rules to the type identification and the using declaration. But [namespace.udecl]/3 says each using-declarator shall either name an enumerator or have a nested-name-specifier naming a base class of the current class.
> > > >
> > > > So now I think Clang is simply confused and this is a bug.
> > >
> > > `Base` in this context refers to Base's injected class name, which is inaccessible
> > > (unlikne `::Base`).
> >
> > From outside the class, either form is accessible. From the context of
> > "using", which requires "naming a base class of the current class",
> > neither form is accessible.
>
> In the case of `Base::member`, it's the `Base` part that's inaccessible
> inside Derived, regardless of the using declaration. You'd get the same
> error if you tried to use it in a different context inside the class.
>
> `::Base::member` is accessible inside the class when it refers to the
> member declaration, as in:
>
> struct Derived : Middle {
> decltype(::Base::member) member2;
> };
>
> It's the subobject that's inaccessible, as in:
>
> struct Derived : Middle {
> void f() {
> // translates to `decltype(this->::Base::member)`
> decltype(::Base::member) member2;
> }
> };
>
> Obviously, I agree that `using Base::member` shouldn't be valid.
That should have been `using ::Base::member`
> On Tuesday, May 12th, 2026 at 4:56 PM, Yongwei Wu <wuyongwei_at_[hidden]> wrote:
>
> > On Tue, 12 May 2026 at 21:46, Ell <ell.ell.se_at_[hidden]> wrote:
> > >
> > > On Tuesday, May 12th, 2026 at 2:49 PM, Yongwei Wu via Std-Discussion <std-discussion_at_[hidden]> wrote:
> > >
> > > > Actually, if we change
> > > >
> > > > struct Derived : public Middle { public: using ::Base::member; };
> > > >
> > > > to
> > > >
> > > > struct Derived : public Middle { public: using Base::member; };
> > > >
> > > > Clang will reject the code. So it seems to me that Clang is applying different rules to the type identification and the using declaration. But [namespace.udecl]/3 says each using-declarator shall either name an enumerator or have a nested-name-specifier naming a base class of the current class.
> > > >
> > > > So now I think Clang is simply confused and this is a bug.
> > >
> > > `Base` in this context refers to Base's injected class name, which is inaccessible
> > > (unlikne `::Base`).
> >
> > From outside the class, either form is accessible. From the context of
> > "using", which requires "naming a base class of the current class",
> > neither form is accessible.
>
> In the case of `Base::member`, it's the `Base` part that's inaccessible
> inside Derived, regardless of the using declaration. You'd get the same
> error if you tried to use it in a different context inside the class.
>
> `::Base::member` is accessible inside the class when it refers to the
> member declaration, as in:
>
> struct Derived : Middle {
> decltype(::Base::member) member2;
> };
>
> It's the subobject that's inaccessible, as in:
>
> struct Derived : Middle {
> void f() {
> // translates to `decltype(this->::Base::member)`
> decltype(::Base::member) member2;
> }
> };
>
> Obviously, I agree that `using Base::member` shouldn't be valid.
That should have been `using ::Base::member`
Received on 2026-05-12 14:22:34
