From: Jeff Schwab on
Bob wrote:
> On Jan 30, 12:48 am, Klaus Rudolph <lts-rudo...(a)gmx.de> wrote:

>> compiles on g++ 4.5 with c++0x and also older 4.2.1 without problems

> slightly modified code:

> bool operator<=(const E &, const E &) {
> return false;
> }

> gives:
> test.cpp:12: error: ambiguous overload for 'operator<=' in 'val <=
> val'
> test.cpp:12: note: candidates are: operator<=(E, E) <built-in>
> test.cpp:12: note: operator<=(int, int) <built-in>
> test.cpp:5: note: bool operator<=(const E&, const E&)
>
> with g++ 4.4.1 (TDM-2 mingw32)

You added pass-by-reference. See [over.match.viable] P3 in the c++0x
draft standard:

If the parameter has reference type, the implicit conversion
sequence includes the operation of binding the reference,

Binding an enum to a reference-to-enum apparently counts as one
conversion step, making it no better a match for operator<= than
conversion of enum to int. GCC seems to handle this correctly.

The OP's problem appears to be that VC++9 defines built-in operator<=
for enumerated type, and that frankly is just broken. I'm curious what
it does for other operators, since I sometimes use them to achieve
modular arithmetic semantics, e.g. ++december == january.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Johannes Schaub (litb) on
Bob wrote:

> On Jan 30, 12:48 am, Klaus Rudolph <lts-rudo...(a)gmx.de> wrote:
>> Hi,
>>
>> compiles on g++ 4.5 with c++0x and also older 4.2.1 without problems
>> (main is not void, use int instead).
>>
>
> Hi,
> slightly modified code:
>
> enum E {
> e1
> };
>
> bool operator<=(const E &, const E &) {
> return false;
> }
>
> int main()
> {
> E val = e1;
> val<=val;
> }
>
> gives:
> test.cpp:12: error: ambiguous overload for 'operator<=' in 'val <=
> val'
> test.cpp:12: note: candidates are: operator<=(E, E) <built-in>
> test.cpp:12: note: operator<=(int, int) <built-in>
> test.cpp:5: note: bool operator<=(const E&, const E&)
>
> with g++ 4.4.1 (TDM-2 mingw32)
>

In fact, i was wrong in my answer (happens if you try answering without
having lookup up xD). A few builtin overload candidates directly have
enumerated types as parameters. operator<= is one of them (see the list in
13.6). Still Arno's code as written before seem to was correct - the
Standard says about the builtin overload candidates that only such are
included that among others "do not have the same parameter type list as any
non-template non-member candidate." - in Arno's first testcase this wasn't
the case and so the candidate wasn't added.

In this second testcase, the own candidate has a different parameter type
list, and so won't prevent the builtin candidate from being added. The
builtin candidate will be an equally good match (the "const" there has no
effect on comparison with the "E -> E" candidate: "E -> E const&" is not a
const qualification conversion, and is only worse than a "E -> E&" by
special rules).


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]