Skip to content

Cpp Improved Enum

Morten Hattesen edited this page Dec 10, 2022 · 7 revisions

WORK IN PROGRESS

Feature overview

Note: adding enum value constructor and/or members removes the "classic enum" representation via ineger values and the ability to assign integers directly to the enum value.

Built-in Iterator Support

// C++Ng proposed
enum class BinaryOperator {Add, Subtract, Multiply, Divide};

std::cout << "Number of enum values: " << BinaryOperator.size() << endl;
// Output: Number of enum values: 4

for (auto& op : BinaryOperator) {
  std::cout << std::string(op);
}
// Output: 0, 1, 2, 3

Built-in to/from string

// C++Ng proposed
enum class BinaryOperator {Add, Subtract, Multiply, Divide};

BinaryOperator divOp = BinaryOperator.from("Divide"); // questionable implementation: no access to constructor, return static member

std::cout << std::string(BinaryOperator::Multiply) << " and " << std::string(divOp) << endl;
// Multiply and Divide

Optional Constructor and Members

// C++Ng proposed
<template T>
class BinaryOperator {
  enum { // enum class syntax needs to be adjusted to allow general class operations to be applied
    Add("+"),
    Subtract("-"),
    Multiply("*"),
    Divide("/")
  }

private:
  // Only privately constructable
  BinaryOperator(const std:string& rep): rep{rep} {}
  const string rep;

public:
  template <class T>
  std::ostream& operator << (ostream os&, const BinaryOperator bo);

  template <class T>
  virtual T operator() (const T lh, const T rh) = 0;
};

std::ostream& operator << (ostream os&, BinaryOperator bo) {
  ostream << bo.rep;
}

int main() {
  std::cout "Add: " << BinaryOperator::Add << std::endl;
  // Output: Add: +

  BinaryOperator multiply = BinaryOperator::Multiply;
  int lh = 2;
  int rh = 3;
  std::cout << lh << multiply << rh << " = " << multiply(2, 3) << endl;
  // Output: 2*3 = 6 
}

Adding member functions to enum values

// C++Ng proposed
enum class BinaryOperator {
    // enum class syntax needs to be adjusted to allow general class operations to be applied
    Add("+") {
      template <class T>
      T operator(const T lh, const T rh) const {return lh + rh;}
    },
    Subtract("-") {
      template <class T>
      T operator(const T lh, const T rh) const {return lh - rh;}
    },
    Multiply("*") {
      template <class T>
      T operator(const T lh, const T rh) const {return lh * rh;}
    },
    Divide("/") {
      template <class T>
      T operator(const T lh, const T rh) const {return lh / rh;}
    }
}

int main () {
  using enum BinaryOperator {
    std::cout << "2 * (3 + 4) = " << Multiply(2, Add(3, 4)) << std::endl;
    // Output: 2 * (3 + 4) = 14
  }
}