Bug 53499 - Incorrect partial ordering result with member vs non-member
Summary: Incorrect partial ordering result with member vs non-member
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
: 66914 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-05-27 13:58 UTC by Johannes Schaub
Modified: 2018-01-12 21:51 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-07-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Schaub 2012-05-27 13:58:06 UTC
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);
}
Comment 1 Johannes Schaub 2012-05-27 14:00:20 UTC
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.
Comment 2 Jonathan Wakely 2015-07-17 15:29:58 UTC
*** Bug 66914 has been marked as a duplicate of this bug. ***
Comment 3 Ed Catmur 2018-01-12 20:51:47 UTC
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
}