Неявные преобразования из класса перечисления не найдут определяемые пользователем операторы [дубликат]C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Неявные преобразования из класса перечисления не найдут определяемые пользователем операторы [дубликат]

Сообщение Anonymous »

Проблема
Рассмотрите код ниже:
  •  — определяемый пользователем тип без операторов.
  • Код: Выделить всё

    WithPlus
     – это определяемый пользователем тип с оператором+, определенный как бесплатная функция.
  • Существует неявный конструктор WithPlus из MyType

Код: Выделить всё

struct MyType {};

struct WithPlus {
WithPlus(MyType m) {}
};

WithPlus operator+(WithPlus, WithPlus) { return WithPlus{MyType{}}; }

auto result = MyType{} + MyType{};
Результат: Тип результата определяется как WithPlus, поскольку компилятор вызывает оператор+ путем неявного преобразования обоих объектов MyType.
Проблема, с которой я столкнулся, заключается в том, что когда базовым типом является класс перечисления, это не работает.

Код: Выделить всё

enum class MyType {};

struct WithPlus {
WithPlus(MyType m) {}
};

WithPlus operator+(WithPlus, WithPlus) { return WithPlus{MyType{}}; }

auto result = MyType{} + MyType{};
Результат:

ошибка: нет совпадения для «operator+» (типы операндов: «MyType» и «MyType»)

Справочная информация
Я пытаюсь создать класс Bitmask, где T — это класс перечисления. Идея состоит в том, чтобы определить побитовые операторы, например:

Код: Выделить всё

Bitmask operator|(Bitmask, Bitmask)
Затем, сделав Bitmask неявно конструируемым из T, я хочу позволить пользователю вводить:

Код: Выделить всё

Bitmask mask = EnumClass::value1 | EnumClass::value2;
Очень раздражает то, что неявные преобразования не могут найти здесь оператора|. Обычно неявное преобразование обеих сторон оператора нежелательно (отсюда и трюк со скрытым другом), но теперь, когда я действительно хочу, чтобы это работало, оно не работает.
Вопрос
Почему вышеописанное работает для структуры MyType, но не для класса Enum MyType? И есть ли способ заставить его делать то, что я хочу?
Изменить
При использовании именованной функции вместо оператора происходит неявное преобразование. Таким образом, класс enum участвует в преобразованиях, определяемых пользователем, но по какой-то причине не для операторов. Приведенный ниже код компилируется и вызывает func(WithPlus, WithPlus):

Код: Выделить всё

enum class MyType {};

struct WithPlus {
WithPlus(MyType m) {}
};

WithPlus func(WithPlus, WithPlus) { return WithPlus{MyType{}}; }

auto result = func(MyType{}, MyType{});
Но этот код не компилируется:

Код: Выделить всё

enum class MyType {};

struct WithPlus {
WithPlus(MyType m) {}
};

WithPlus operator+(WithPlus, WithPlus) { return WithPlus{MyType{}}; }

auto result = MyType{} + MyType{};
Я хочу знать, почему func и operator+ ведут себя здесь по-разному. Ответ не "

Код: Выделить всё

enum class
не преобразует неявно`, потому что при компиляции приведенного выше кода он делает это при преобразовании, определяемом пользователем.
Я знаю, что он не преобразует неявно в int, это не мой вопрос.
EDIT2
Я думаю, что нашел ответ здесь. Не стесняйтесь закрыть дубликат этого вопроса (хотя это определенно не дубликат вопроса «почему класс enum безопаснее»)

Подробнее здесь: https://stackoverflow.com/questions/798 ... -operators
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»