Reputation: 1073
I have two enumerations with underlying type uint32_t
. and I need constexpr OR operator for them because some of members should consist with result of OR of other members. I wanted to avoid to implement the operator twice or more times.
So, I tried to use template to achieve it.
template <enum class E>
constexpr uint32_t operator|(const E& left, const E& right)
{
return (uint32_t)left | (uint32_t)right;
}
template <enum class E>
constexpr uint32_t operator|(const uint32_t& left, const E& right)
{
return left | (uint32_t)right;
}
enum class U32Enum1 : uint32_t {
OtherMember1 = 0x01L,
OtherMember2 = 0x02L,
SomeOfMember = OtherMember1 | OtherMember2 // Not work
}
enum class U32Enum2 : uint32_t {
OtherMember1 = 0x01L,
OtherMember2 = 0x02L,
SomeOfMember = OtherMember1 | OtherMember2 // Not work
}
However, It won't work and compiler gave me a message that no matching operands for operator |
. How can I accomplish this?
Upvotes: 0
Views: 55
Reputation: 217225
template <enum class E>
is not the good syntax, you might do instead:
template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
constexpr E operator|(const E& left, const E& right)
{
return static_cast<E>((uint32_t)left | (uint32_t)right);
}
and using underlying type is even better:
template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
constexpr E operator|(const E& left, const E& right)
{
using T = typename std::underlying_type<E>::type;
return static_cast<E>(static_cast<T>(left) | static_cast<T>(right));
}
Upvotes: 3