enum operator overload ambiguity

  • Follow


Hello,

is this expected behavior or a bug in Visual C++ 9?

enum E {
	e1
};

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

void main()
{
	E e1;
	e1<=e1;
}

leads to compiler error

test6.cpp(10): could be 'bool operator <=(E,E)'
or       'built-in C++ operator<=(E, E)'
while trying to match the argument list '(E, E)'

TIA,

Arno

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

0
Reply aschoedl (17) 1/28/2010 7:19:01 PM

On Jan 29, 10:19 am, Arno <ascho...@think-cell.com> wrote:
> enum E { e1 };
>
> bool operator<=( E, E ) { return false; }
>
> void main()
> {
>     E e1;
>     e1 <= e1;
> }
>
> test6.cpp(10): could be 'bool operator <=(E,E)'
> or       'built-in C++ operator<=(E, E)'
> while trying to match the argument list '(E, E)'

I didn't bother digging through the Standard, but it compiles under
SparcWorks 5.8 and GNU 3.4.3 (after changing main()'s return type to
int)...

Cheers,
Tony


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

0
Reply Tony 1/29/2010 5:44:58 PM


Arno wrote:

> Hello,
> 
> is this expected behavior or a bug in Visual C++ 9?
> 
> enum E {
> e1
> };
> 
> bool operator<=( E, E ) {
> return false;
> }
> 
> void main()
> {
> E e1;
> e1<=e1;
> }
> 
> leads to compiler error
> 
> test6.cpp(10): could be 'bool operator <=(E,E)'
> or       'built-in C++ operator<=(E, E)'
> while trying to match the argument list '(E, E)'
> 

There is no built-in C++ operator<=(E, E). Builtin overload candidates are
instead added for integers, and the promotion rules will choose an
unambiguous match in case you haven't overloaded with enumeration
parameters. But since you have, yours is a better match.

Notice that VC++ is correct if you are actually very pedantic: You have an
error in your code ("void main"), and the compiler gives you a diagnostic.

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

0
Reply Johannes 1/29/2010 5:45:39 PM

Hi,

compiles on g++ 4.5 with c++0x and also older 4.2.1 without problems
(main is not void, use int instead).




> enum E {
> 	e1
> };
> 
> bool operator<=( E, E ) {
> 	return false;
> }
> 
> void main()
> {
> 	E e1;

?? Should it be E val=e1; ??


> 	e1<=e1;
and val<=val;
??


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

0
Reply Klaus 1/29/2010 5:48:01 PM

On Jan 30, 12:48 am, Klaus Rudolph <lts-rudo...@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)


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

0
Reply Bob 1/29/2010 9:44:28 PM

Bob wrote:
> On Jan 30, 12:48 am, Klaus Rudolph <lts-rudo...@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! ]

0
Reply Jeff 1/30/2010 2:16:19 PM

Bob wrote:

> On Jan 30, 12:48 am, Klaus Rudolph <lts-rudo...@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! ]

0
Reply Johannes 1/30/2010 2:16:38 PM

6 Replies
478 Views

(page loaded in 0.092 seconds)

Similiar Articles:





7/21/2012 2:00:48 AM


Reply: