enum class
От: Videoman Россия https://hts.tv/
Дата: 26.05.18 12:26
Оценка:
В С++ есть замечательная возможность объявить класс перечисления. При этом, мы защищаемся от случайного перехода от целых к перечислениям и обратно. Тут все понятно.
Теперь, в некоторых перечислениях, хотелось бы иметь логические операции |,|=,&,&=,~ и т.д. для работы с флагами. Это тоже без проблем можно сделать, перегрузить операторы и т.д.
Теперь, хотелось бы избавиться от рутины и добавить для всего этого шаблоны, но по некому условию, только если надо, иначе, шаблон для всех перечислений очень "жадная" штука и применяется вообще везде, где надо и не надою.
Есть подход в лоб для этого и он много где описан, в том числе на StackOverflow, типа такого:
template<typename Enum>  
struct EnableBitMaskOperators  
{
    static const bool enable = false;
};

template<typename Enum>  
typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type  
operator |(Enum lhs, Enum rhs)  
{
    using underlying = typename std::underlying_type<Enum>::type;
    return static_cast<Enum> (
        static_cast<underlying>(lhs) |
        static_cast<underlying>(rhs)
    );
}

Соответственно где нужно можно написать:
template<>  
struct EnableBitMaskOperators<MyEnum>  
{
    static const bool enable = true;
};

и все работает без проблем.

Теперь что не устраивает и что хотелось бы получить:
1. Данных подход очень не удобен в случае если у нас множество вложенных наймспейсов. Каждый раз приходится "лесенкой" выходит их них, а потом объявлять шаблон полностью квалифицируя именя. Типа:
//...
} // namespace n1
} // namespace n2

template<>  
struct EnableBitMaskOperators<n1:n2::MyEnum>  
{
    static const bool enable = true;
};

namespace n1
{
namespace n2
{
//...

2. У нас флаги очень часто используются внутри классов. В этом случае все еще сильнее усложняется.
3. Для флагов в защищенных секциях данный подход вообще не работает.
4. Необходимо не использовать макросы.

В общем, кто как решает данную проблему и что можете посоветовать?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.