Date: Tue, 12 May 2026 14:16:49 +0000
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.
> 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.
Received on 2026-05-12 14:17:06
