I think that this is ambiguous for partial ordering ambiguities, but GCC accepts this code, selecting the non-member template <class P> class ptr { public: // Picked in C++11 mode. template<class T> void operator- (T) const { static_assert(sizeof(T) == 0, "#1"); } }; // Picked in default C++ mode. template<class T1, class T2> void operator- (const ptr<T1>&, const ptr<T2>&) { static_assert(sizeof(T1) == 0, "#2"); } int main () { ptr <int> a, b; (void) (b - a); }
Sorry, GCC picks the same function (non-member) disregarding of the C++ Standards mode. The comments were a left-over from a clang bug report.
*** Bug 66914 has been marked as a duplicate of this bug. ***
I believe this also causes gcc to reject (as ambiguous) the example in [temp.func.order]/3: struct A { }; template<class T> struct B { template<class R> int operator*(R&); // #1 }; template<class T, class R> int operator*(T&, R&); // #2 // The declaration of B::operator* is transformed into the equivalent of // template<class R> int operator*(B<A>&, R&); // #1a int main() { A a; B<A> b; b * a; // calls #1a }
hmm, for the test in comment #0, GCC, ICC and MSVC all have the same behavior of picking #2 while clang's result is the different one here where it says operator- is ambiguous.
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:c1e54c82a9e1855499ef7bb8827540e6a097532b commit r14-6221-gc1e54c82a9e1855499ef7bb8827540e6a097532b Author: Jason Merrill <jason@redhat.com> Date: Tue Dec 5 15:28:16 2023 -0500 c++: partial ordering of object parameter [PR53499] Looks like we implemented option 1 (skip the object parameter) for CWG532 before the issue was resolved, and never updated to the final resolution of option 2 (model it as a reference). More recently CWG2445 extended this handling to static member functions; I think that's wrong, and have opened CWG2834 to address that and how explicit object member functions interact with it. The FIXME comments are to guide how the explicit object member function support should change the uses of DECL_NONSTATIC_MEMBER_FUNCTION_P. The library testsuite changes are to make partial ordering work again between the generic operator- in the testcase and _Pointer_adapter::operator-. DR 532 PR c++/53499 gcc/cp/ChangeLog: * pt.cc (more_specialized_fn): Fix object parameter handling. gcc/testsuite/ChangeLog: * g++.dg/template/partial-order4.C: New test. * g++.dg/template/spec26.C: Adjust for CWG532. libstdc++-v3/ChangeLog: * testsuite/23_containers/vector/ext_pointer/types/1.cc * testsuite/23_containers/vector/ext_pointer/types/2.cc (N::operator-): Make less specialized.
*** Bug 113117 has been marked as a duplicate of this bug. ***
Fixed for GCC 14.
*** Bug 83371 has been marked as a duplicate of this bug. ***