-1

Unscoped enumeration WORKS with the OR operator where the scoped one does not... WHY and how to work with it?

The enum type type-name is unscoped. Prefer 'enum class' over 'enum' (Enum.3)

#include <iostream>

enum  eDogType
{
  eHusk = 0,
  eGold,
  eAus,
  eGerm,
  ePud
};


int main()
{
  eDogType eDog1 = eDogType::eAus;
  eDogType eDog2 = eDogType::eGerm;
  
  eDogType eDog = static_cast<eDogType>(eDog1 | eDog2);  // WORKS


  std::cout << "Hello World: " << eDog << "\n";

  return(0);
}

Scoped enumeration fails in the OR operator

#include <iostream>

enum class eDogType
{
  eHusk = 0,
  eGold,
  eAus,
  eGerm,
  ePud
};


int main()
{
  eDogType eDog1 = eDogType::eAus;
  eDogType eDog2 = eDogType::eGerm;
  
  eDogType eDog = static_cast<eDogType>(eDog1 | eDog2); // FAILS: C++ no operator matches these operands


  std::cout << "Hello World: " << eDog << "\n";

  return(0);
}
jdl
  • 6,151
  • 19
  • 83
  • 132
  • 1
    Is this supposed to be a question? – EOF Feb 19 '21 at 18:25
  • Added in the question – jdl Feb 19 '21 at 18:27
  • I'd vote to close for duplicate of https://stackoverflow.com/q/64494432/3185968 , but I've already voted to close for unclear because there was no question here originally. Maybe others can now vote to close for dupe? – EOF Feb 19 '21 at 18:32
  • I suggest to use a `template operator |` function, that highly simplifies ORing of _any_ `enum` type: `template [[nodiscard]] constexpr inline T operator| (T v1, T v2) { typedef typename std::underlying_type_t type; return T((type)v1 | (type)v2); }` – prapin Feb 19 '21 at 19:59

1 Answers1

2

enum eDogType values are processed as int values, where enum class eDogType values are not (they are processed as values of type eDogType).

So in the first case, the operator | (int, int) is used, whereas in the second case, the operator | (eDogType, eDogType) is needed (but not found).


#include <iostream>

enum class  eDogType
{
  eHusk = 0,
  eGold,
  eAus,
  eGerm,
  ePud
};


int main()
{
  eDogType eDog1 = eDogType::eAus;
  eDogType eDog2 = eDogType::eGerm;
  
  eDogType eDog = static_cast<eDogType>(static_cast<int>(eDog1) | static_cast<int>(eDog2));


  std::cout << "Hello World: " << static_cast<int>(eDog) << "\n";

  return(0); 
}
jdl
  • 6,151
  • 19
  • 83
  • 132
limserhane
  • 1,022
  • 1
  • 6
  • 17
  • more work to scope the enum into a class... – jdl Feb 19 '21 at 18:32
  • 1
    it really depends on your needs; besides, take care : if you want to use something like `ePug | eGerm`, enum values must be 1, 2, 4, 8 ... so that the binay OR behaves as expected – limserhane Feb 19 '21 at 18:36