After reading through How to write a Java-enum-like class with multiple data fields in C ? I decided to give it a try and added some functionality to it. In order to abstract this functionality I've put it in a separate class EnumClass<T>
. But since these abstracted features have to be static in the implementation but not in the original class I would need to do something like:
class Planet : public static EnumClass<Planet>
Which is not allowed. Is there some other way to do this? I got around it by adding a static instance of EnumClass<Planet>
to Planet
, but it is not really optimal:
template<class T, uint64_t S>
class EnumClass {
public:
const T elements[S];
const uint64_t length = S;
template<typename F>
const T find(F lambda) const {
for (int i = 0; i < S; i ) {
if (lambda(elements[i])) {
return elements[i];
}
}
return NULL;
}
};
template <class T, class... U>
EnumClass(T, U...) -> EnumClass<T, 1 sizeof...(U)>;
class Planet {
public:
static const Planet MERCURY;
static const Planet VENUS;
static constexpr EnumClass ENUM = { &MERCURY, &VENUS };
private:
double massValue;
double radiusValue;
private:
Planet(double massValue, double radiusValue) {
this->massValue = massValue;
this->radiusValue = radiusValue;
}
public:
double mass() const {
return this->massValue;
}
double radius() const {
return this->radiusValue;
}
static const Planet* findByMass(double massValue) {
return ENUM.find([massValue](const Planet * element) { return element->mass() == massValue; });
}
static const Planet* findByRadius(double radiusValue) {
return ENUM.find([radiusValue](const Planet * element) { return element->radius() == radiusValue; });
}
};
// Enum value DEFINITIONS
const Planet Planet::MERCURY = Planet(3.303e 23, 2.4397e6);
const Planet Planet::VENUS = Planet(4.869e 24, 6.0518e6);
CodePudding user response:
If you want members of EnumClass
to be static then just make them static. static
as in class Planet : public static EnumClass<Planet>
does not make sense. You cannot turn non-static members into static members like that.
#include <array>
#include <iostream>
#include <cstddef>
template<class T,size_t S>
class EnumClass {
public:
static const std::array<const T*,S> elements;
static const size_t length = S;
template<typename F>
static const T* find(F lambda) {
for (int i = 0; i < S; i ) {
if (lambda(elements[i])) {
return elements[i];
}
}
return NULL;
}
};
class Planet : EnumClass<Planet,2> {
public:
static const Planet MERCURY;
static const Planet VENUS;
//static constexpr EnumClass ENUM = { &MERCURY, &VENUS };
private:
double massValue;
double radiusValue;
private:
Planet(double massValue, double radiusValue) {
this->massValue = massValue;
this->radiusValue = radiusValue;
}
public:
double mass() const {
return this->massValue;
}
double radius() const {
return this->radiusValue;
}
static const Planet* findByMass(double massValue) {
return find([massValue](const Planet * element) { return element->mass() == massValue; });
}
static const Planet* findByRadius(double radiusValue) {
return find([radiusValue](const Planet * element) { return element->radius() == radiusValue; });
}
};
// Enum value DEFINITIONS
const Planet Planet::MERCURY = Planet(3.303e 23, 2.4397e6);
const Planet Planet::VENUS = Planet(4.869e 24, 6.0518e6);
template <>
const std::array<const Planet*,2> EnumClass<Planet,2>::elements{{&Planet::MERCURY,&Planet::VENUS}};