From mboxrd@z Thu Jan 1 00:00:00 1970 From: Martin Sebor To: gdr@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org Subject: Re: c++/3585: wrong function overload resolution? Date: Fri, 06 Jul 2001 09:56:00 -0000 Message-id: <20010706165601.23865.qmail@sourceware.cygnus.com> X-SW-Source: 2001-07/msg00163.html List-Id: The following reply was made to PR c++/3585; it has been noted by GNATS. From: Martin Sebor To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/3585: wrong function overload resolution? Date: Fri, 06 Jul 2001 10:53:13 -0600 gawrilow@math.tu-berlin.de wrote: > > >Number: 3585 > >Category: c++ > >Synopsis: wrong function overload resolution? ... > >Description: > Let's consider the following fragment: > > void f(int& x) { } // #1 > > void f(int x) { } // #2 > > int temp() { return 0; } > > int main() { > int var=0; > f(var); // should resolve to #1 > f(temp()); // resolves to #2 > } > > The gcc rejects f(var) as ambiguous reasoning that #1 and #2 > were equally good. IMHO, resolving to #2 includes an > lvalue-to-rvalue conversion, where #1 incurs an identity > conversion, thus being better. Am I missing something? I think so: Reference Binding is considered the Identity conversion (see 13.3.3.1.4, p1). > > The things become yet prettier as we move to templates. > Let's change the definitions of f's to the following: > > template void f(T& x) { } // #1 > template void f(T x) { } // #2 > > gcc 3.0 still considers this ambiguous, while 2.95 has > chosen #1 for f(var) without any complains. The call to f (var) is also ambiguous here. Argument deduction finds [T = int] in both cases and you're left with the same as above. > > Thus the final questions: who understands the overload > resolution rules better: gcc 3.0, gcc 2.95, > me (obviously not!), or somebody else? I'd say 3.0 is correct here and 2.95 is in error. Most other compilers agree. > > How could I otherwise distinct between rvalue and lvalue > arguments to an overloaded function, without using > f(const T&) ? Here's how you can tell an lvalue from an rvalue: bool is_lvalue (...) { return false; } template bool is_lvalue (T&) { return true; } Regards Martin