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).