Mainly that.
Choosing a class instead of a namespace as container of the enumerator
names is mostly gut-feeling. With class the names can be inherited into
another class, and they can be referred to in a succinct manner via a
local short type alias. With namespace the names can be made available
for unqualified use in a local scope via `using namespace`, or referred
to in a succinct manner via a namespace alias, but not in a class scope.
Classes also become almost /necessary/ to express enum generalizations.
For example, 0 is an Input_stream_id; 1 and 2 are Output_stream_id; and
any Input_stream_id or Output_stream_id is a general Stream_id.
Unfortunately class inheritance goes the wrong way for expressing enum
relationships directly, so in the experimental code below (what a more
concise syntax would have to be translated to) there are just implicit
conversions from Input_stream_id and Output_stream_id to Stream_id:
// struct Input_stream_id{ enum Enum{ in = 0 }; };
// struct Output_stream_id{ enum Enum{ out = 1, err = 2 }; };
class Input_stream_id;
struct Input_stream_id_names
{
static const Input_stream_id in; // 0
};
class Output_stream_id;
struct Output_stream_id_names
{
static const Output_stream_id out; // 1
static const Output_stream_id err; // 2
};
class Input_stream_id:
public Input_stream_id_names
{
const int m_value;
public:
explicit constexpr Input_stream_id( const int value ): m_value(
value ) {}
constexpr operator int() const { return m_value; }
};
class Output_stream_id:
public Output_stream_id_names
{
const int m_value;
public:
explicit constexpr Output_stream_id( const int value ):
m_value( value ) {}
constexpr operator int() const { return m_value; }
};
class Stream_id:
public Input_stream_id_names,
public Output_stream_id_names
{
const int m_value;
public:
explicit constexpr Stream_id( const int value ): m_value( value
) {}
constexpr Stream_id( const Input_stream_id value ): m_value(
value ) {}
constexpr Stream_id( const Output_stream_id value ): m_value(
value ) {}
constexpr operator int() const { return m_value; }
};
inline constexpr Input_stream_id Input_stream_id_names::in
= Input_stream_id( 0 );
inline constexpr Output_stream_id Output_stream_id_names::out
= Output_stream_id( 1 );
inline constexpr Output_stream_id Output_stream_id_names::err
= Output_stream_id( 2 );
- Alf