This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


2730. Comparison templates on enumeration types

Section: 12.2.2.3  [over.match.oper]     Status: open     Submitter: Tobias Loew     Date: 2023-05-11

Equality and relational comparisons are supported for all enumeration types, even for scoped enumerations, as specified in 12.5 [over.built] paragraph 15 and 7.6.9 [expr.rel] paragraph 6:

If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield true if the specified relationship is true and false if it is false.

The comparisons can be overloaded using a non-template function, for example:

  enum class F {
    a, b
  };
  
  bool operator<(F,F) = delete;
  bool b = F::a < F::b;   // error, as intended

However, using a function template does not work:

  template<typename E>
  inline constexpr bool X = false;  // specialize to disable comparisons on E

  template <typename E> requires X<E>
  void operator<(E, E) = delete;

  template <>
  inline constexpr bool X<F> = true;

  bool b = F::a < F::b;             // ok, selects built-in comparison per 12.2.4.1 [over.match.best.general] bullet 2.4

The reason is that the built-in operator candidates are not suppressed if they compete with a template specialization.

Suggested resolution:

Change in 12.2.2.3 [over.match.oper] bullet 3.3.4 as follows: