У меня есть два класса: CoolEnum
, который является попыткой превратить enum class
в реальный класс с методами;template <class WrapMe> class Wrapper;
, который неявно преобразуется в const WrapMe&
Я предложил следующую реализацию:
#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;
}
Я, конечно, могу просто static_cast
Wrapper<CoolEnum>
в CoolEnum
, но я полагаю, что можно исправить CoolEnum
класс и избежать его.
Одно из известных мне решений - удалить operator Impl
из CoolEnum
, и я полагаю, потому что этоприводит к неоднозначности (хотя я не до конца понимаю, почему).Чтобы уточнить, я полагаю, что есть несколько возможностей для operator ==
:
преобразование Wrapper
в CoolEnum
и сравнение
преобразование *От 1029 * до Impl
и сравните
... (возможно, другие)
, но кажется, что это должно быть тривиально разрешено -все они генерируются компилятором и приводят к одному и тому же результату
У меня два вопроса:
Почему именно я получаю ошибку компиляции?
Какое самое лучшее исправление для CoolEnum
класса?
Спасибо!