https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I don't know if that rule applies here. If it did, this would be invalid too
(by [over.load]/2.1), but all compilers agree that this is OK:

struct Base {
  int method() {}
};

struct Derived : Base {
  using Base::method;
  void method() {}
};


I believe the relevant rule for my example is [namespace.udecl[/14 which says
that declarations from a base class are hidden by declarations in the derived
class with the same name, parameter clause and ref-qualifier (if any), and that
hidden names are excluded from the set introduced by the using-declaration.
Which means that Base::method() is hidden by Derived::method() and so not
introduced.

It looks like GCC is applying that same rule for the original example, so that
Derived::method() hides the Base::method() const& and Base::method const&&
declarations that would otherwise conflict. That means the only overload
candidate for test.method() is Derived::method() which can't be called on a
const object. However, [namespace.udecl]/14 seems clear that such hiding should
only happen if the ref-qualifers are the same.

Other compilers (Clang, EDG and MSVC) accept the original example, which I
can't explain. Either the overloads should conflict because of [over.load]/2.3
(and the definition of Derived should be ill-formed) or they should be hidden
and not visible in Derived (so the call to test.method() should be ill-formed).

Reply via email to