I would like to create a composite type out of two enum classes
.
enum class Color {RED, GREEN, BLUE};
enum class Shape {SQUARE, CIRCLE, TRIANGLE};
You don't need a linear index, you can simply compare them lexicographically:
friend bool operator< (const Object &lhs, const Object &rhs) {
if (lhs.color < rhs.color) return true;
else if (lhs.color > rhs.color) return false;
else return lhs.shape < rhs.shape;
}
That's a good question, but you don't actually need the number of Color
to compare them :
friend bool operator< (const Object &lhs, const Object &rhs) {
if(lhs.color > rhs.color) {
return false;
}
if(lhs.color < rhs.color) {
return true;
}
return lhs.shape < rhs.shape;
}
What you are trying to express is that to determine the order of your Objects, you first need to compare the color, and then check the shape in case the color was the same. Instead of linearizing that, if would simply use boolean operators.
friend bool operator< (const Object &lhs, const Object &rhs)
{
return ( (lhs.color < rhs.color)
|| ( (lhs.color == rhs.color ) && ( lhs.shape < rhs.color) ) )
}
EDIT: Actually, you can also use an upper bound for the number of objects, the behaviour will be the same:
friend bool operator< (const Object &lhs, const Object &rhs) {
return 10000*lhs.color+lhs.shape < 10000*rhs.color+rhs.shape;
}
but that introduces a "magic number" (so not such a good idea).
You only need to compare shape
if color
is the same for both.
Using a ternary you can make it look nice too:
friend bool operator< (const Object &lhs, const Object &rhs) {
return lhs.color == rhs.color ? (lhs.shape < rhs.shape)
: (lhs.color < rhs.color);
}
As commented and as already stated by others, give precedence to either Shape
or Color
in the operator<
and only compare the other if the first is equal.
An alternative implementation for operator<
using std::tie:
#include <tuple>
friend bool operator<(const Object& lhs, const Object& rhs)
{
return std::tie(lhs.color, lhs.shape) < std::tie(rhs.color, rhs.shape);
}
Consider using simply std::tuple<Color, Shape>
as the "composite enum." This will come with comparison operators already defined for you, using a dictionary ordering. For example, valid code:
bool b = std::make_tuple(Color::RED, Shape::CIRCLE)
< std::make_tuple(Color::GREEN, Shape::SQUARE);