I have two classes: CoolEnum, which is an attempt to turn enum class into a real class with methods; template <class WrapMe> class Wrapper;, which is implicitly convertible to const WrapMe&
I've come up with the following implementation:
#include <cassert>
class CoolEnum {
public:
enum Impl {
kFirst, kSecond
};
explicit CoolEnum(Impl value) : value_(value) {
}
operator Impl() const {
return value_;
}
CoolEnum Inverse() const {
switch (value_) {
case kFirst:
return CoolEnum{kSecond};
default:
return CoolEnum{kFirst};
}
}
private:
Impl value_;
};
template <class WrapMe>
class Wrapper {
public:
Wrapper(WrapMe value, char other_info)
: value_(value), other_info_(other_info) {
}
operator const WrapMe&() const {
return value_;
}
private:
WrapMe value_;
char other_info_;
};
int main() {
// compiles
assert(CoolEnum(CoolEnum::kFirst) == CoolEnum::kFirst);
// does not compile: no match for operator ==
assert(CoolEnum(CoolEnum::kFirst)
== Wrapper<CoolEnum>(CoolEnum(CoolEnum::kFirst), 'e'));
return 0;
}
I surely can just static_cast Wrapper<CoolEnum> to CoolEnum, but I believe that it might be possible to fix CoolEnum class and avoid it.
One of the solutions I know of is to remove operator Impl from CoolEnum, and I guess its because it results in ambiguity (though I don't fully understand why). To elaborate, I believe there are several possibilities for operator ==:
convert
WrappertoCoolEnumand compareconvert
WrappertoImpland compare... (maybe others)
but it seems like it should trivially be allowed -- all of them are compiler-generated, and lead to the same result
I have two questions:
Why exactly do I get a compilation error?
What is the best possible fix for
CoolEnumclass?
Thanks!
operator==definition?