Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value comparison #13

Closed
Chaosvex opened this issue Dec 1, 2015 · 3 comments
Closed

Value comparison #13

Chaosvex opened this issue Dec 1, 2015 · 3 comments

Comments

@Chaosvex
Copy link

Chaosvex commented Dec 1, 2015

This could be a case of missing something in the documentation but I couldn't find any mention that comparisons don't work as you'd typically expect.

That is, the following will fail with an overload resolution error:

BETTER_ENUM(Channel, int, Red, Green, Blue)

Channel channel = Channel::Red;

if(channel == Channel::Red) // channel.value_ is fine

I'll admit to not going through all of the documentation (tried a search and a few examples) since I wanted a quick evaluation of the library and I'm not interested in the more advanced capabilities but this seems like something that, if it can't be fixed, should be made fairly clear.

Thanks!

@aantron
Copy link
Owner

aantron commented Dec 1, 2015

Hi, try this for your comparison:

channel == +Channel::Red

(just the + is different). In general, with Better Enums, if you run into overload resolution errors while using literal constants, try prefixing with +.

You're on to something with the documentation – I've been meaning to reorganize it. Some months after writing it, the problems with it are much more obvious to me. Things such as this issue should be much more clear.

If you want to know what's going on with the +, it's that Channel::Red is a value of type Channel::_enumerated, while channel is, of course, a value of type Channel. So, the compiler starts looking for a type within one implicit conversion of each at which to compare these values. Since Channel is convertible by a user-defined conversion to Channel::_enumerated (I did this for switch), it is implicitly convertible to that enum type, and also every numeric type. Since Channel is not already any of these types, the compiler does not prefer any of them for applying the == operator, and you get an ambiguity error.

The + "promotes" Channel::_enumerated to Channel, so now both operands are of the same type, and there is a preferred type to do the comparison at. The + is a no-op at run time.

I would love to eliminate both the conversions to integral type and the +, but I haven't found a way that is completely satisfactory. However, you can see this.

aantron added a commit that referenced this issue Dec 10, 2015
Fixes #13.
Fixes #14.

[ci skip]
@exhau
Copy link

exhau commented Nov 3, 2016

@aantron
Why not just remove these free-stand comparison functions ?
Compiler will do the implicit conversion to enum type.

if "Strict conversions" is turned on, then add these functions back.

@aantron
Copy link
Owner

aantron commented Nov 7, 2016

@exhau This is quite out of my brain's cache right now (swamped by other work). However, IIRC, removing these operators and letting the compiler choose implicit conversions results in ambiguous choices, which is an error.

As you may be able to tell from other issues, this is a part of Better Enums that I'd like to improve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants