C ++ 11 Оператор перегрузки для помещенного в класс перечисляемого класса - PullRequest
0 голосов
/ 09 мая 2018

это моя первая попытка использовать классы enum для моих проектов, но у меня проблема в том, что я не могу скомпилировать свой код, если класс enum размещен внутри другого класса. Я пытаюсь определить перегрузку оператора, как в моем примере, и я пытаюсь сделать это и снаружи. Все работает нормально, если я помещаю enum-класс за пределы класса. В чем дело? Как перегрузить оператор, если я, что бы использовать его, поместил в класс?

#include <cstdint>

namespace MyNamespace
{
    class MyClass
    {
    public:
        enum class MyEnum_t
        {
            VALUE_0 = 0x0,
            VALUE_1 = 0x1,
            VALUE_2 = 0x2,
            VALUE_3 = 0x4,
            VALUE_4 = 0x8 
       };

        inline MyEnum_t &operator|(MyEnum_t lhs, MyEnum_t rhs)
        {
            return static_cast<MyEnum_t>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
        }
}

int main()
{
    MyNamespace::MyClass::MyEnum_t test = MyNamespace::MyClass::MyEnum_t::VALUE_0;

    test = MyNamespace::MyClass:MyEnum_t::VALUE_1 | MyNamespace::MyClass::MyEnum_t::VALUE_2;

    return 0;
}

Ответы [ 4 ]

0 голосов
/ 10 мая 2018

Как вы написали следующую строку кода main ():

test = MyNamespace :: MyClass: MyEnum_t :: VALUE_1 | MyNamespace :: MyClass :: MyEnum_t :: VALUE_2;

Ожидается оператор пространства имен, поэтому оператор должен находиться вне MyClass (но внутри MyNamespace):

MyClass::MyEnum_t operator|(MyClass::MyEnum_t lhs, MyClass::MyEnum_t rhs)
{
    return static_cast<MyClass::MyEnum_t>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
}

также, как указано в ответе выше, вы не можете вернуть временную память (в качестве ссылки), поэтому либо возвращайте по значению, либо определяйте статическую переменную в операторе и возвращайте ее.

0 голосов
/ 10 мая 2018

Фиксированный код для оператора:

inline MyClass::MyEnum_t operator|(MyClass::MyEnum_t lhs, MyClass::MyEnum_t rhs)
{
    return static_cast<MyClass::MyEnum_t>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
}
0 голосов
/ 10 мая 2018

Я бы написал так:

class MyClass
{
public:
    enum class MyEnum_t
    {
        VALUE_0 = 0x0,
        VALUE_1 = 0x1,
        VALUE_2 = 0x2,
        VALUE_3 = 0x4,
        VALUE_4 = 0x8,
    };

    friend MyEnum_t operator|(MyEnum_t lhs, MyEnum_t rhs)
    {
        using UT = std::underlying_type<MyEnum_t>::type;
        return static_cast<MyEnum_t>(static_cast<UT>(lhs) | static_cast<UT>(rhs));
    }
};

Таким образом, больше не имеет значения, находится ли MyClass в namespace, и правильный underlying_type используется для выполнения побитовой математики.

0 голосов
/ 09 мая 2018

Класс enum может находиться внутри другого класса, но определение оператора должно находиться в области имен.

Также обратите внимание, что оператор вычисляет новое значение и, как таковой, он не может вернуть ссылку, поскольку не было бы ничего, с чем ссылка могла бы связываться. Вместо этого он должен возвращать значение.

Всего:

namespace MyNamespace
{
    class MyClass
    {
    public:
        enum class MyEnum_t
        {
            VALUE_0 = 0x0,
            VALUE_1 = 0x1,
            VALUE_2 = 0x2,
            VALUE_3 = 0x4,
            VALUE_4 = 0x8 
       };
    };

    inline MyClass::MyEnum_t operator|(MyClass::MyEnum_t lhs, MyClass::MyEnum_t rhs)
    {
       return static_cast<MyEnum_t>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
    }
}
...