Is there a way in C++ to extend/"inherit" enums?
I.E:
enum Enum {A,B,C};
enum EnumEx : public Enum {D,E,F};
or at least define a conversion between them?
No, there is not.
enum are really the poor thing in C++, and that's unfortunate of course.
Even the class enum introduced in C++0x does not address this extensibility issue (though they do some things for type safety at least).
The only advantage of enum is that they do not exist: they offer some type safety while not imposing any runtime overhead as they are substituted by the compiler directly.
If you want such a beast, you'll have to work yourself:
create a class MyEnum, that contains an int (basically)
create named constructors for each of the interesting values
you may now extend your class (adding named constructors) at will...
That's a workaround though, I have never found a satistifying way of dealing with an enumeration...
I've solved in this way:
typedef enum
{
#include "NetProtocols.def"
} eNetProtocols, eNP;
Of course, if you add a new net protocol in the NetProtocols.def file, you have to recompile, but at least it's expandable.
"NetProtocols.def" will contain only the field names:
HTTP,
HTTPS,
FTP
I had this problem in some projects that ran on small hardware devices I design. There is a common project that holds a number of services. Some of these services use enums as parameters to get additional type checking and safety. I needed to be able to extend these enums in the projects that use these services.
As other people have mentioned c++ doesn't allow you to extend enums. You can however emulate enums using a namespace and a template that has all the benefits of enum class.
enum class has the following benefits:
Converts to a known integer type.
Is a value type
Is constexpr by default and takes up no valuable RAM on small processors
Is scoped and accessible by enum::value
Works in case statements
Provides type safety when used as a parameter and needs to be explicitly cast
Now if you define a class as an enum you can't create constexpr instances of the enum in the class declaration, because the class is not yet complete and it leads to a compile error. Also even if this worked you could not extend the value set of enums easily later in another file/sub project .
Now namespaces have no such problem but they don't provide type safety.
The answer is to first create a templated base class which allows enums of different base sizes so we don't waste what we don't use.
template <typename TYPE>
class EnumClass {
private:
TYPE value_;
public:
explicit constexpr EnumClass(TYPE value) :
value_(value){
}
constexpr EnumClass() = default;
~EnumClass() = default;
constexpr explicit EnumClass(const EnumClass &) = default;
constexpr EnumClass &operator=(const EnumClass &) = default;
constexpr operator TYPE() const {return value_;}
constexpr TYPE value() const {return value_;}
};
Then for each enum class we want to extend and emulate we create a namespace and a Type like this:
namespace EnumName {
class Type :public Enum<uint8_t> {
public:
explicit constexpr Type(uint8_t value): Enum<uint8_t>(value){}
constexpr Enum() = default;
}
constexpr auto Value1 = Type(1);
constexpr auto Value2 = Type(2);
constexpr auto Value3 = Type(3);
}
Then later in your code if you have included the original EnumName you can do this:
namespace EnumName {
constexpr auto Value4 = Type(4U);
constexpr auto Value5 = Type(5U);
constexpr auto Value6 = Type(6U);
constexpr std::array<Type, 6U> Set = {Value1, Value2, Value3, Value4, Value5, Value6};
}
now you can use the Enum like this:
#include <iostream>
void fn(EnumName::Type val){
if( val != EnumName::Value1 ){
std::cout << val;
}
}
int main(){
for( auto e :EnumName::Set){
switch(e){
case EnumName::Value1:
std::cout << "a";
break;
case EnumName::Value4:
std::cout << "b";
break;
default:
fn(e);
}
}
}
So we have a case statement, enum comparisons, parameter type safety and its all extensible. Note the set is constexpr and wont end up using valuable RAM on a small micro (placement verified on Godbolt.org. :-). As a bonus we have the ability to iterate over a set of enum values.
If you were able to create a subclass of an enum it'd have to work the other way around.
The set of instances in a sub-class is a subset of the instances in the super-class. Think about the standard "Shape" example. The Shape class represents the set of all Shapes. The Circle class, its subclass, represents the subset of Shapes that are Circles.
So to be consistent, a subclass of an enum would have to contain a subset of the elements in the enum it inherits from.
(And no, C++ doesn't support this.)
A simple, but useful workaround for this c++ gap could be as follows:
#define ENUM_BASE_VALS A,B,C
enum Enum {ENUM_BASE_VALS};
enum EnumEx {ENUM_BASE_VALS, D,E,F};
Actually you can extend enums in a round about way.
The C++ standard defines the valid enum values to be all the valid values of the underlying type so the following is valid C++ (11+). Its not Undefined Behaviour, but it is very nasty - you have been warned.
#include <cstdint>
enum Test1:unit8_t {
Value1 =0,
Value2 =1
};
constexpr auto Value3 = static_cast<Test1>(3);
constexpr auto Value4 = static_cast<Test1>(4);
constexpr auto Value5 = static_cast<Test1>(5);
Test1 fn(Test1 val){
switch(val){
case Value1:
case Value2:
case Value3:
case Value4:
return Value1;
case Value5:
return Value5;
}
}
int main(){
return static_cast<uint8_t>(fn(Value5));
}
Note that most of the compilers don't consider the additional values as part of the set for generating warnings about missing enums values in switch statements.So
clang and gcc will warn if Value2 is missing but will do nothing if Value4 is missing in the above switch statement.
One might try this :)
struct EnumType
{
enum
{
None = 0,
Value_1 = 1,
Value_2 = 2,
Value_3 = 3
};
//For when using the EnumType as a variable type
int Value { None };
};
struct EnumTypeEx : EnumType
{
enum
{
ExValue_1 = 3,
ExValue_2 = 4,
//override the value of Value_3
Value_3 = 3000
};
};
Pros:
Class like extensibility
Can override base labels value
Cons:
Tedious to write
You have to explicitly set the value for each label(*)
(*) you can start the auto value increment from the last base value by just writing it explicitly eg. ExValue_Start = LastBaseValue.
I do this
enum OPC_t // frame Operation Codes
{
OPC_CVSND = 0 // Send CV value
, OPC_CVREQ = 1 // Request CV (only valid for master app)
, OPC_COMND = 2 // Command
, OPC_HRTBT = 3 // Heart Beat
};
enum rxStatus_t // this extends OPC_t
{
RX_CVSND = OPC_CVSND // Send CV value
, RX_CVREQ = OPC_CVREQ // Request CV
, RX_COMND = OPC_COMND // Command
, RX_HRTBT = OPC_HRTBT // Heart Beat
, RX_NONE // No new Rx
, RX_NEWCHIP // new chip detected
};
http://www.codeproject.com/KB/cpp/InheritEnum.aspx goes over a method to created an expanded enum.
Create InheritEnum.h:
// -- InheritEnum.h
template <typename EnumT, typename BaseEnumT>
class InheritEnum
{
public:
InheritEnum() {}
InheritEnum(EnumT e)
: enum_(e)
{}
InheritEnum(BaseEnumT e)
: baseEnum_(e)
{}
explicit InheritEnum( int val )
: enum_(static_cast<EnumT>(val))
{}
operator EnumT() const { return enum_; }
private:
// Note - the value is declared as a union mainly for as a debugging aid. If
// the union is undesired and you have other methods of debugging, change it
// to either of EnumT and do a cast for the constructor that accepts BaseEnumT.
union
{
EnumT enum_;
BaseEnumT baseEnum_;
};
};
And then to use:
enum Fruit { Orange, Mango, Banana };
enum NewFruits { Apple, Pear };
typedef InheritEnum< NewFruit, Fruit > MyFruit;
void consume(MyFruit myfruit);
YMMV.
Just an idea:
You could try to create an empty class for each constant (maybe put them all in the same file to reduce clutter), create one instance of each class and use the pointers to these instances as the "constants". That way, the compiler will understand inheritance and will perform any ChildPointer-to-ParentPointer conversion necessary when using function calls, AND you still get type-safety checks by the compiler to ensure no one passes an invalid int value to functions (which would have to be used if you use the LAST value method to "extend" the enum).
Haven't fully thought this through though so any comments on this approach are welcome.
And I'll try to post an example of what I mean as soon as I have some time.
My approach slightly differs from that chosen by Marco.
I have added a macro as the last value of the enum I want to extend. In a separate header, I have defined that macro with the enum entries I want to add.
// error.h
#ifndef __APP_DEFINED__
#define __APP_DEFINED__
#endif
typedef enum { a, b, c, __APP_DEFINED__ } Error;
To add more values, I have created
// app_error.h
#define __APP_DEFINED__ d, e, f,
Lastly, I have added -include app_error.h to the compiler flags.
I prefer this approach compared to placing an #include "app_error.h" directive within the enum, mainly because I need the freedom not to have the "app_error.h" file at all in some projects.
The following code works well.
enum Enum {A,B,C};
enum EnumEx {D=C+1,E,F};
Related
I'm already fairly sure what I'm about to ask isn't possible without creating my own enum implamentation, but I thought it was worth putting it out there in case there's something I've missed, because it would simplify a situation I come across quite often both at work and in my own projects.
Basically, I would like a generic way of returning a list of all enums in an enum class, or at least a generic way of returning all positive enums up until an enum-specific but otherwise pre-determined point. Ok, that last idea was confusing, so I'll post pseudo code of what I mean below...
A way of setting a specific enum "key?" that is used to return the number of positive enums up until the given key:
template<typename EnumType>
std::vector<EnumType> getFullEnumList()
{
std::vector<EnumType> fullEnumList;
for (enumIndex = 0; enumIndex < EnumType::NumEnums; enumIndex++)
fullEnumList.push_back(static_cast<EnumType>(enumIndex));
return fullEnumList;
}
I'm guessing this wouldn't be a practical thing to implement as stated above because the compiler doesn't care what I've called each enum class value, only it's value and class type... that all that compiler deals with in the final compilation stages right?
My first idea I guess would involve some kind of:
EnumClass::size()
...function, which I already know doesn't exist, but I don't currently know enough about the specifics of an enum class to understand why this wouldn't be possible to implement in future c++ iterations... I'm guessing it's either not possible, or it would be an undesirable extra overhead in most enum class use cases, otherwise they'd have implemented it years ago...
But to narrow down to my actual question, on top of the extra knowledge nuggets you guys could furnish me with regarding the above musings, is there some generic way of doing this I haven't thought of?
Cheers in advance for your insights,
Pete
If you are using Enums with sequential values, your could use this old trick.
Define a Max (and an optional Min) value for each Enum you have:
enum class MyEnum
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Max,
Min = Sunday // (Optional, see following notes)
};
Define your enumeration method as following:
template<typename EnumType>
std::vector<EnumType>
getFullEnumList(int from = (int)EnumType::Min, int to = (int)EnumType::Max)
{
std::vector<EnumType> fullEnumList;
for (auto enumIndex = from; enumIndex < to; enumIndex++)
fullEnumList.push_back(static_cast<EnumType>(enumIndex));
return fullEnumList;
}
The use of EnumType::Min and EnumType::Max as default values will protect from invocations of this method for Enum types that are not defined properly.
Note: If all your Enums use positive values only, you can avoid the decleration of Min and use int from = 0 for getFullEnumList.
And use this method trivially:
auto enumsList = getFullEnumList<MyEnum>();
-- OR --
auto enumsList = getFullEnumList<MyEnum>(2, 4);
If you have some regular enum (just sequental values, not flags) you can quickly achive that by using bounding values:
enum t_MyEnum
{
enum_begin
, monday = enum_begin
, tuesday
...
, sunday
, enum_end
, enum_items_cout = enum_end - enum_begin
};
The more flexibale way would be to implement some enum type traits.
// traits
template<typename TEnum> class t_Integral
{
public: using t_Type = int;
};
template<typename TEnum> class t_FirstItem;
template<typename TEnum> class t_LastItem;
template<typename TEnum> class t_ItemsCount
{
public: static constexpr const ::std::size_t value
{
static_cast<::std::size_t>
(
static_cast<typename t_Integral<TEnum>::t_Type>(t_LastItem<TEnum>::value)
-
static_cast<typename t_Integral<TEnum>::t_Type>(t_FirstItem<TEnum>::value)
+
1
)
};
};
// enum
enum class t_MyEnum
: ::std::uint16_t
{
monday
, tuesday
...
, sunday
};
// specialize traits (can also be done to third-party enums)
template<> class t_Integral<t_MyEnum>
{
public: using t_Type = ::std::uint16_t;
};
template<> class t_FirstItem<t_MyEnum>
{
public: static constexpr const auto value{t_MyEnum::monday};
};
template<> class t_LastItem<t_MyEnum>
{
public: static constexpr const auto value{t_MyEnum::sunday};
};
// now we have a generic way to get enum items count and can use it somehow...
::std::array< int, t_ItemsCount<t_MyEnum>::value > items;
Enum type traits can define stuff like enum item names (as strings) and corresponding conversion function, separation of enums by kind ("sequential enum", "sparse enum", "bit flags enum"), iteration over enum values, null values and so on.
You can solve this in a simple way by using the Qt framework if you don’t mind the dependency.
Have a look on QMetaEnum, esp. the keyCount function.
The usage is described by this accepted answer to a StackOverflow question: You basically have to attach the Q_ENUM(myEnum) macro to your enum definition myEnum in the class myEnumClass
Afterwards you get the corresponding QMetaEnum object by calling QMetaEnum myMetaEnum = QMetaEnum::fromType<myEnumClass::enumName>();
Intro
The enum type in C++ is fairly basic; it basically just creates a bunch of compile-time values for labels (potentially with proper scoping with enum class).
It's very attractive for grouping related compile-time constants together:
enum class Animal{
DOG,
CAT,
COW,
...
};
// ...
Animal myAnimal = Animal::DOG;
However it has a variety of perceived shortcomings, including:
No standard way to get the number of possible elements
No iteration over elements
No easy association of enum with string
In this post, I seek to create a type that addresses those perceived shortcomings.
An ideal solution takes the notion of compile-time knowledge of constants and their associations with strings and groups them together into an scoped-enum-like object that is searchable both by enum id and enum string name. Finally, the resulting type would use syntax that is as close to enum syntax as possible.
In this post I'll first outline what others have attempted for the individual pieces, and then walk through two approaches, one that accomplishes the above but has undefined behavior due to order of initialization of static members, and another solution that has less-pretty syntax but no undefined behavior due to order of initialization.
Prior work
There are plenty of questions on SO about getting the number of items in an enum (1 2 3) and plenty of other questions on the web asking the same thing (4 5 6) etc. And the general consensus is that there's no sure-fire way to do it.
The N'th element trick
The following pattern only works if you enforce that enum values are positive and increasing:
enum Foo{A=0, B, C, D, FOOCOUNT}; // FOOCOUNT is 4
But is easily broken if you're trying to encode some sort of business logic that requires arbitrary values:
enum Foo{A=-1, B=120, C=42, D=6, FOOCOUNT}; // ????
Boost Enum
And so the developers at Boost attempted to solve the issue with Boost.Enum which uses some fairly complicated macros to expand into some code that will at least give you the size.
Iterable Enums
There have been a few attempts at iterable enums; enum-like objects that one can iterate over, theoretically allowing for implicit size computation, or even explicitly in the case of [7] (7 8 9, ...)
Enum to String conversion
Attempts to implement this usually result in free-floating functions and the use of macros to call them appropriately. (8 9 10)
This also covers searching enums by string (13)
Additional Constraints
No macros
Yes, this means no Boost.Enum or similar approach
Need int->Enum and Enum-int Conversion
A rather unique problem when you start moving away from actual enums;
Need to be able to find enum by int (or string)
Also a problem one runs into when they move away from actual enums. The list of enums is considered a collection, and the user wants to interrogate it for specific, known-at-compile-time values. (See iterable enums and Enum to String conversion)
At this point it becomes pretty clear that we cannot really use an enum anymore. However, I'd still like an enum-like interface for the user
Approach
Let's say I think that I'm super clever and realize that if I have some class A:
struct A
{
static int myInt;
};
int A::myInt;
Then I can access myInt by saying A::myInt.
Which is the same way I'd access an enum:
enum A{myInt};
// ...
// A::myInt
I say to myself: well I know all my enum values ahead of time, so an enum is basically like this:
struct MyEnum
{
static const int A;
static const int B;
// ...
};
const int MyEnum::A = 0;
const int MyEnum::B = 1;
// ...
Next, I want to get fancier; let's address the constraint where we need std::string and int conversions:
struct EnumValue
{
EnumValue(std::string _name): name(std::move(_name)), id(gid){++gid;}
std::string name;
int id;
operator std::string() const
{
return name;
}
operator int() const
{
return id;
}
private:
static int gid;
};
int EnumValue::gid = 0;
And then I can declare some containing class with static EnumValues:
MyEnum v1
class MyEnum
{
public:
static const EnumValue Alpha;
static const EnumValue Beta;
static const EnumValue Gamma;
};
const EnumValue MyEnum::Alpha = EnumValue("Alpha")
const EnumValue MyEnum::Beta = EnumValue("Beta")
const EnumValue MyEnum::Gamma = EnumValue("Gamma")
Great! That solves some of our constraints, but how about searching the collection? Hm, well if we now add a static container like unordered_map, then things get even cooler! Throw in some #defines to alleviate string typos, too:
MyEnum v2
#define ALPHA "Alpha"
#define BETA "Beta"
#define GAMMA "Gamma"
// ...
class MyEnum
{
public:
static const EnumValue& Alpha;
static const EnumValue& Beta;
static const EnumValue& Gamma;
static const EnumValue& StringToEnumeration(std::string _in)
{
return enumerations.find(_in)->second;
}
static const EnumValue& IDToEnumeration(int _id)
{
auto iter = std::find_if(enumerations.cbegin(), enumerations.cend(),
[_id](const map_value_type& vt)
{
return vt.second.id == _id;
});
return iter->second;
}
static const size_t size()
{
return enumerations.size();
}
private:
typedef std::unordered_map<std::string, EnumValue> map_type ;
typedef map_type::value_type map_value_type ;
static const map_type enumerations;
};
const std::unordered_map<std::string, EnumValue> MyEnum::enumerations =
{
{ALPHA, EnumValue(ALPHA)},
{BETA, EnumValue(BETA)},
{GAMMA, EnumValue(GAMMA)}
};
const EnumValue& MyEnum::Alpha = enumerations.find(ALPHA)->second;
const EnumValue& MyEnum::Beta = enumerations.find(BETA)->second;
const EnumValue& MyEnum::Gamma = enumerations.find(GAMMA)->second;
Full working demo HERE!
Now I get the added benefit of searching the container of enums by name or id:
std::cout << MyEnum::StringToEnumeration(ALPHA).id << std::endl; //should give 0
std::cout << MyEnum::IDToEnumeration(0).name << std::endl; //should give "Alpha"
BUT
This all feels very wrong. We're initializing a LOT of static data. I mean, it wasn't until recently that we could populate a map at compile time! (11)
Then there's the issue of the static-initialization order fiasco:
A subtle way to crash your program.
The static initialization order fiasco is a very subtle and commonly
misunderstood aspect of C++. Unfortunately it’s very hard to detect —
the errors often occur before main() begins.
In short, suppose you have two static objects x and y which exist in
separate source files, say x.cpp and y.cpp. Suppose further that the
initialization for the y object (typically the y object’s constructor)
calls some method on the x object.
That’s it. It’s that simple.
The tragedy is that you have a 50%-50% chance of dying. If the
compilation unit for x.cpp happens to get initialized first, all is
well. But if the compilation unit for y.cpp get initialized first,
then y’s initialization will get run before x’s initialization, and
you’re toast. E.g., y’s constructor could call a method on the x
object, yet the x object hasn’t yet been constructed.
I hear they’re hiring down at McDonalds. Enjoy your new job flipping
burgers.
If you think it’s “exciting” to play Russian Roulette with live rounds
in half the chambers, you can stop reading here. On the other hand if
you like to improve your chances of survival by preventing disasters
in a systematic way, you probably want to read the next FAQ.
Note: The static initialization order fiasco can also, in some cases,
apply to built-in/intrinsic types.
Which can be mediated with a getter function that initializes your static data and returns it (12):
Fred& GetFred()
{
static Fred* ans = new Fred();
return *ans;
}
But if I do that, now I have to call a function to initialize my static data, and I lose the pretty syntax you see above!
#Questions#
So, now I finally get around to my questions:
Be honest, how bad is the above approach? In terms of initialization order safety and maintainability?
What kind of alternatives do I have that are still pretty for the end user?
EDIT
The comments on this post seem to indicate a strong preference for static accessor functions to get around the static order initialization problem:
public:
typedef std::unordered_map<std::string, EnumValue> map_type ;
typedef map_type::value_type map_value_type ;
static const map_type& Enumerations()
{
static map_type enumerations {
{ALPHA, EnumValue(ALPHA)},
{BETA, EnumValue(BETA)},
{GAMMA, EnumValue(GAMMA)}
};
return enumerations;
}
static const EnumValue& Alpha()
{
return Enumerations().find(ALPHA)->second;
}
static const EnumValue& Beta()
{
return Enumerations().find(BETA)->second;
}
static const EnumValue& Gamma()
{
return Enumerations().find(GAMMA)->second;
}
Full working demo v2 HERE
Questions
My Updated questions are as follows:
Is there another way around the static order initialization problem?
Is there a way to perhaps only use the accessor function to initialize the unordered_map, but still (safely) be able to access the "enum" values with enum-like syntax? e.g.:
MyEnum::Enumerations()::Alpha
or
MyEnum::Alpha
Instead of what I currently have:
MyEnum::Alpha()
Regarding the bounty:
I believe an answer to this question will also solve the issues surrounding enums I've elaborated in the post (Enum is in quotes because the resulting type will not be an enum, but we want enum-like behavior):
getting the size of an "enum"
string to "enum" conversion
a searchable "enum".
Specifically, if we could do what I've already done, but somehow accomplish syntax that is enum-like while enforcing static initialization order, I think that would be acceptable
Sometimes when you want to do something that isn't supported by the language, you should look external to the language to support it. In this case, code-generation seems like the best option.
Start with a file with your enumeration. I'll pick XML completely arbitrarily, but really any reasonable format is fine:
<enum name="MyEnum">
<item name="ALPHA" />
<item name="BETA" />
<item name="GAMMA" />
</enum>
It's easy enough to add whatever optional fields you need in there (do you need a value? Should the enum be unscoped? Have a specified type?).
Then you write a code generator in the language of your choice that turns that file into a C++ header (or header/source) file a la:
enum class MyEnum {
ALPHA,
BETA,
GAMMA,
};
std::string to_string(MyEnum e) {
switch (e) {
case MyEnum::ALPHA: return "ALPHA";
case MyEnum::BETA: return "BETA";
case MyEnum::GAMMA: return "GAMMA";
}
}
MyEnum to_enum(const std::string& s) {
static std::unordered_map<std::string, MyEnum> m{
{"ALPHA", MyEnum::ALPHA},
...
};
auto it = m.find(s);
if (it != m.end()) {
return it->second;
}
else {
/* up to you */
}
}
The advantage of the code generation approach is that it's easy to generate whatever arbitrary complex code you want for your enums. Basically just side-step all the problems you're currently having.
I usually prefer non-macro code but in this case, I don't see what's wrong with macros.
IMHO, for this task macros are a much better fit as they are simpler and shorter to write and to read, and the same goes for the generated code. Simplicity is a goal in its own right.
These 2 macro calls:
#define Animal_Members(LAMBDA) \
LAMBDA(DOG) \
LAMBDA(CAT) \
LAMBDA(COW) \
CREATE_ENUM(Animal,None);
Generate this:
struct Animal {
enum Id {
None,
DOG,
CAT,
COW
};
static Id fromString( const char* s ) {
if( !s ) return None;
if( strcmp(s,"DOG")==0 ) return DOG;
if( strcmp(s,"CAT")==0 ) return CAT;
if( strcmp(s,"COW")==0 ) return COW;
return None;
}
static const char* toString( Id id ) {
switch( id ) {
case DOG: return "DOG";
case CAT: return "CAT";
case COW: return "COW";
default: return nullptr;
}
}
static size_t count() {
static Id all[] = { None, DOG, CAT, COW };
return sizeof(all) / sizeof(Id);
}
};
You could wrap them into a single macro using BOOST_PP and have a sequence for the members. This would make it a lot less readable, though.
You can easily change it to your preferences of default return values, or remove the default altogether, add a specific member value and string name, etc.
There's no loose functions, no init order hell, and only a bit of macro code that looks very much like the final result:
#define ENUM_MEMBER(MEMBER) \
, MEMBER
#define ENUM_FROM_STRING(MEMBER) \
if( strcmp(s,#MEMBER)==0 ) return MEMBER;
#define ENUM_TO_STRING(MEMBER) \
case MEMBER: return #MEMBER;
#define CREATE_ENUM_1(NAME,MACRO,DEFAULT) \
struct NAME { \
enum Id { \
DEFAULT \
MACRO(ENUM_MEMBER) \
}; \
static Id fromString( const char* s ) { \
if( !s ) return DEFAULT; \
MACRO(ENUM_FROM_STRING) \
return DEFAULT; \
} \
static const char* toString( Id id ) { \
switch( id ) { \
MACRO(ENUM_TO_STRING) \
default: return nullptr; \
} \
} \
static size_t count() { \
static Id all[] = { DEFAULT \
MACRO(ENUM_MEMBER) }; \
return sizeof(all) / sizeof(Id); \
} \
};
#define CREATE_ENUM_2(NAME,DEFAULT) \
CREATE_ENUM_1(NAME,NAME##_Members,DEFAULT)
#define CREATE_ENUM(NAME,DEFAULT) \
CREATE_ENUM_2(NAME,DEFAULT)
Hope this helps.
I am aware that you can use part of an enum as a parameter for a function. The question I have is can you use an entire enum as a parameter?
For the enum:
enum exampleEnum {ONE,TWO,THREE}
by partial enum I am referring to:
function example(exampleEnum value){}
function example(ONE);
by entire enum is:
function example(enum value){}
function example(exampleEnum);
I guess what I am asking is can I pass an enum like you pass an array. At least that is what I think I am asking.
edit
The effect I am trying to achieve is to share an enum across multiple classes and subclasses without redefining it in every class/subclass I wish to use it in. I want these values to be passed instead of using some form a global variable.
edit of the edit
To be more specific... I am using the enum values as a form of associative array.
enum attribute{STR,DEX,CON,INT,WIS,CHA};
short int charAttributes[6];
charAttributes[STR] = sumValue;
charAttributes[DEX] = sumValue;
charAttributes[CON] = sumValue;
charAttributes[INT] = sumValue;
charAttributes[WIS] = sumValue;
charAttributes[CHA] = sumValue;
What I am wanting is to pass the enumeration in its entirety name, values, everything to be passed as a parameter. I am wanting to pass the enumeration to keep the enumeration names and values to continue using them as such.
exampleEnum is a type, not a value.
C++ way to pass type to functions is using templates:
#include <iostream>
#include <ostream>
#include <typeinfo>
using namespace std;
enum exampleEnum {ONE,TWO,THREE};
template<typename T>
void example()
{
cout << typeid(T).name() << endl;
}
int main()
{
example<exampleEnum>();
return 0;
}
If you structure your enum values properly, you can combine values with the | bit-wise or operator.
enum exampleEnum {One=0x01, TWO=0x02, THREE=0x04, FOUR=0x08}; // one bit set in each
example(ONE | TWO | FOUR);
In your function you need to test for each value individually:
if (value & ONE) // ONE was passed
if (value & TWO) // TWO was passed, etc.
The effect I am trying to achieve is to share an enum across multiple classes and subclasses without redefining it in every class/subclass I wish to use it in. I want these values to be passed instead of using some form a global variable.
Hm, you don't have to redefine it. Just place enum definition outside of these classes. And when you want to use enum values in some class, just include header with that enum.
enum exampleEnum {ONE,TWO,THREE};
class Class1
{
void foo()
{
exampleEnum t=TWO; // use enum values here
}
};
class Class2
{
void bar()
{
exampleEnum t=ONE; // and here
}
};
class Class3
{
void some()
{
exampleEnum t=THREE; // and even here
}
};
EDIT:
By doing it this way I would be adding a dependency to my classes which I am try to avoid. It's better to give something to a class then to have the class take something. While I cannot completely escape from dependencies I was hoping I might have been able to.
In that case you may use templates:
enum exampleEnum {ONE,TWO,THREE};
enum exampleEnumOther {RAZ,DVA,TRI};
template<typename Enum>
class Class1
{
Enum member;
public:
void foo(Enum p)
{
member=p;
}
template<typename OtherEnum>
void bar(OtherEnum val)
{
OtherEnum use=val;
}
};
int main()
{
Class1<exampleEnum> t;
t.foo(ONE);
t.bar(TWO);
t.bar(RAZ);
}
Class1 do not depend on any particular enum.
If your enumeration is contiguous (or, if you never use = in the definition of your enum), there is an easy to do trick is to iterate over the enum.
Start with this:
enum /*class*/ Bob // class optional
{
BeginBob,
ONE = BeginBob, // the first entry needs an = Begin clause.
TWO,
THREE,
EndBob
};
now, you can pass in a range of enum values in a similar way you'd pass an iterator range.
void doWork( Bob b );
void doWork( Bob begin, Bob end )
{
for (Bob i = begin; i != end; i=ststic_cast<Bob>(i+1) )
doWork( i );
}
the begin and end enum values describe a half-open range, like iterators would. So you can call doWork on the entire enum range like this:
void doWork( BeginBob, EndBob );
or, you could call it on everything up to, but not including, THREE like this:
void doWork( BeginBob, THREE );
which calls doWork on ONE and TWO.
You can make template <typename T> example and specialize it on several different enums, allowing you to call example(ONE) to call code specific to exampleEnum and then (given, say enum otherEnum { EINS, ZWEI, DREI } you can call example(EINS) to get code specific to otherEnum.
Perhaps something similar has already been asked, and sure, it's a nitpick...
I have a bunch of constant std::maps to switch between enum (class) values and their std::string representations (both ways). Someone here pointed out to me that these maps will be initialized at runtime, when other initialization code is run, before my program executes all the good stuff. This would mean constant expressions would impact runtime performance, as the maps are built up from their enum-string pairs.
As an illustrative example, here is an example of one of these maps:
enum class os
{
Windows,
Linux,
MacOSX
};
const map<string, os> os_map =
{ {"windows", os::Windows},
{"linux", os::Linux},
{"mac", os::MacOSX} };
const map<os, string> os_map_inverse =
{ {os::Windows, "windows"},
{os::Linux, "linux"},
{os::MacOSX, "mac"} };
Would the C++11 constexpr have any influence on performance, or is my assumption of a runtime initialization penalty false? I would think a compiler can embed a constant STL container as pure data in the executable, but apparently that may not be as easy as I make it sound?
It's not so much the performance of initialization that is a problem, but the order of initialization. If someone uses your map before main has started (for example at initialization for a namespace scope variable), then you are SOL, because you are not guaranteed that your map has been initialized before the user's initialization uses it.
However you can do this thing at compile time. String literals are constant expressions, as are enumerators. A simple linear-time complexity structure
struct entry {
char const *name;
os value;
};
constexpr entry map[] = {
{ "windows", os::Windows },
{ "linux", os::Linux },
{ "mac", os::Mac }
};
constexpr bool same(char const *x, char const *y) {
return !*x && !*y ? true : (*x == *y && same(x+1, y+1));
}
constexpr os value(char const *name, entry const *entries) {
return same(entries->name, name) ? entries->value : value(name, entries+1);
}
If you use value(a, b) in a constant expression context, and the name you specify doesn't exist, you will get a compile time error because the function call would become non-constant.
To use value(a, b) in a non-constant expression context, you better add safety features, like adding an end marker to your array and throwing an exception in value if you hit the end marker (the function call will still be a constant expression as long as you never hit the end marker).
constexpr does not work on arbitrary expressions, and especially not on things that will use the freestore. map/string will use the freestore, and thus constexpr will not work for initializing them at compile time, and have no code run at runtime.
As for the runtime penalty: Depending on the storage duration of those variables (and I assume static here, which means initialization before main), you will not even be able to measure the penalty, especially not in the code that is using them, assuming you will use them many times, where the lookup has much more "overhead" than the initialization.
But as for everything, remember rule one: Make things work. Profile. Make things fast. In this order.
Ah yes, it's a typical issue.
The only alternative I've found to avoid this runtime initialization is to use plain C structures. If you're willing to go the extra-mile and store the values in a plain C array, you can get static initialization (and reduced memory footprint).
It's one of the reason LLVM/Clang actually use the tblgen utility: plain tables are statically initialized, and you can generate them sorted.
Another solution would be to create a dedicated function instead: for the enum to string conversion it's easy to use a switch and let the compiler optimize it into a plain table, for the string to enum it's a bit more involved (you need if/else branches organized right to get the O(log N) behavior) but for small enums a linear search is as good anyway, in which case a single macro hackery (based off Boost Preprocessor goodness) can get you everything you need.
I have recently found my own best way to furnish an enum. See the code:
enum State {
INIT, OK, ENoFou, EWroTy, EWroVa
};
struct StateToString {
State state;
const char *name;
const char *description;
public:
constexpr StateToString(State const& st)
: state(st)
, name("Unknown")
, description("Unknown")
{
switch(st){
case INIT : name = "INIT" , description="INIT"; break;
case OK : name = "OK" , description="OK"; break;
case ENoFou: name = "ENoFou", description="Error: Not found"; break;
case EWroTy: name = "EWroTy", description="Error: Wrong type"; break;
case EWroVa: name = "EWroVa", description="Error: Wrong value, setter rejected"; break;
// Do not use default to receive a comile-time warning about not all values of enumeration are handled. Need `-Wswitch-enum` in GCC
}
}
};
Extending this example to some universal code, let's name it lib code:
/// Concept of Compile time meta information about (enum) value.
/// This is the best implementation because:
/// - compile-time resolvable using `constexpr name = CtMetaInfo<T>(value)`
/// - enum type can be implemented anywhere
/// - compile-time check for errors, no hidden run-time surprises allowed - guarantied by design.
/// - with GCC's `-Wswitch` or `-Werror=switch` - you will never forget to handle every enumerated value
/// - nice and simple syntaxis `CtMetaInfo(enumValue).name`
/// - designed for enums suitable for everything
/// - no dependencies
/// Recommendations:
/// - write `using TypeToString = CtMetaInfo<Type>;` to simplify code reading
/// - always check constexpr functions assigning their return results to constexpr values
/**\code
template< typename T >
concept CtMetaInfo_CONCEPT {
T value;
const char *name;
// Here could add variables for any other meta information. All vars must be filled either by default values or in ctor init list
public:
///\param defaultName will be stored to `name` if constructor body will not reassign it
constexpr CtMetaInfoBase( T const& val, const char* defaultName="Unknown" );
};
\endcode
*/
/// Pre-declare struct template. Specializations must be defined.
template< typename T >
struct CtMetaInfo;
/// Template specialization gives flexibility, i.e. to define such function templates
template <typename T>
constexpr const char* GetNameOfValue(T const& ty)
{ return CtMetaInfo<T>(ty).name; }
User must define specialization for user's type:
/// Specialization for `rapidjson::Type`
template<>
struct CtMetaInfo<Type> {
using T = Type;
T value;
const char *name;
public:
constexpr CtMetaInfo(T const& val)
: value(val)
, name("Unknown")
{
switch(val){
case kNullType : name = "Null" ; break;
case kFalseType: case kTrueType: name = "Bool" ; break;
case kObjectType : name = "Object"; break;
case kArrayType : name = "Array" ; break;
case kStringType : name = "String"; break;
case kNumberType : name = "Number"; break;
}
}
static constexpr const char* Name(T const& val){
return CtMetaInfo<Type>(val).name;
}
};
/// TEST
constexpr const char *test_constexprvalue = CtMetaInfo<Type>(kStringType).name;
constexpr const char *test_constexprvalu2 = GetNameOfValue(kNullType);
Often, one needs several enumerated types together. Sometimes, one has a name clash. Two solutions to this come to mind: use a namespace, or use 'larger' enum element names. Still, the namespace solution has two possible implementations: a dummy class with nested enum, or a full blown namespace.
I'm looking for pros and cons of all three approaches.
Example:
// oft seen hand-crafted name clash solution
enum eColors { cRed, cColorBlue, cGreen, cYellow, cColorsEnd };
enum eFeelings { cAngry, cFeelingBlue, cHappy, cFeelingsEnd };
void setPenColor( const eColors c ) {
switch (c) {
default: assert(false);
break; case cRed: //...
break; case cColorBlue: //...
//...
}
}
// (ab)using a class as a namespace
class Colors { enum e { cRed, cBlue, cGreen, cYellow, cEnd }; };
class Feelings { enum e { cAngry, cBlue, cHappy, cEnd }; };
void setPenColor( const Colors::e c ) {
switch (c) {
default: assert(false);
break; case Colors::cRed: //...
break; case Colors::cBlue: //...
//...
}
}
// a real namespace?
namespace Colors { enum e { cRed, cBlue, cGreen, cYellow, cEnd }; };
namespace Feelings { enum e { cAngry, cBlue, cHappy, cEnd }; };
void setPenColor( const Colors::e c ) {
switch (c) {
default: assert(false);
break; case Colors::cRed: //...
break; case Colors::cBlue: //...
//...
}
}
Original C++03 answer:
The benefit from a namespace (over a class) is that you can use using declarations when you want.
The problem with using a namespace is that namespaces can be expanded elsewhere in the code. In a large project, you would not be guaranteed that two distinct enums don't both think they are called eFeelings
For simpler-looking code, I use a struct, as you presumably want the contents to be public.
If you're doing any of these practices, you are ahead of the curve and probably don't need to scrutinize this further.
Newer, C++11 advice:
If you are using C++11 or later, enum class will implicitly scope the enum values within the enum's name.
With enum class you will lose implicit conversions and comparisons to integer types, but in practice that may help you discover ambiguous or buggy code.
FYI In C++0x there is a new syntax for cases like what you mentioned (see C++0x wiki page)
enum class eColors { ... };
enum class eFeelings { ... };
I've hybridized the preceding answers to something like this: (EDIT: This is only useful for pre- C++11. If you are using C++11, use enum class)
I've got one big header file that contains all my project enums, because these enums are shared between worker classes and it doesn't make sense to put the enums in the worker classes themselves.
The struct avoids the public: syntactic sugar, and the typedef lets you actually declare variables of these enums within other worker classes.
I don't think using a namespace helps at all. Maybe this is because I'm a C# programmer, and there you have to use the enum type name when referring the values, so I'm used to it.
struct KeySource {
typedef enum {
None,
Efuse,
Bbram
} Type;
};
struct Checksum {
typedef enum {
None =0,
MD5 = 1,
SHA1 = 2,
SHA2 = 3
} Type;
};
struct Encryption {
typedef enum {
Undetermined,
None,
AES
} Type;
};
struct File {
typedef enum {
Unknown = 0,
MCS,
MEM,
BIN,
HEX
} Type;
};
...
class Worker {
File::Type fileType;
void DoIt() {
switch(fileType) {
case File::MCS: ... ;
case File::MEM: ... ;
case File::HEX: ... ;
}
}
I would definitely avoid using a class for this; use a namespace instead. The question boils down to whether to use a namespace or to use unique ids for the enum values. Personally, I'd use a namespace so that my ids could be shorter and hopefully more self-explanatory. Then application code could use a 'using namespace' directive and make everything more readable.
From your example above:
using namespace Colors;
void setPenColor( const e c ) {
switch (c) {
default: assert(false);
break; case cRed: //...
break; case cBlue: //...
//...
}
}
Advantage of using a class is that you can build a full-fledged class on top of it.
#include <cassert>
class Color
{
public:
typedef enum
{
Red,
Blue,
Green,
Yellow
} enum_type;
private:
enum_type _val;
public:
Color(enum_type val = Blue)
: _val(val)
{
assert(val <= Yellow);
}
operator enum_type() const
{
return _val;
}
};
void SetPenColor(const Color c)
{
switch (c)
{
case Color::Red:
// ...
break;
}
}
As the above example shows, by using a class you can:
prohibit (sadly, not compile-time) C++ from allowing a cast from invalid value,
set a (non-zero) default for newly-created enums,
add further methods, like for returning a string representation of a choice.
Just note that you need to declare operator enum_type() so that C++ would know how to convert your class into underlying enum. Otherwise, you won't be able to pass the type to a switch statement.
An difference between using a class or a namespace is that the class cannot be reopened like a namespace can. This avoids the possibility that the namespace might be abused in the future, but there is also the problem that you cannot add to the set of enumerations either.
A possible benefit for using a class, is that they can be used as template type arguments, which is not the case for namespaces:
class Colors {
public:
enum TYPE {
Red,
Green,
Blue
};
};
template <typename T> void foo (T t) {
typedef typename T::TYPE EnumType;
// ...
}
Personally, I'm not a fan of using, and I prefer the fully qualified names, so I don't really see that as a plus for namespaces. However, this is probably not the most important decision that you'll make in your project!
Since enums are scoped to their enclosing scope, it's probably best to wrap them in something to avoid polluting the global namespace and to help avoid name collisions. I prefer a namespace to class simply because namespace feels like a bag of holding, whereas class feels like a robust object (cf. the struct vs. class debate). A possible benefit to a namespace is that it can be extended later - useful if you're dealing with third-party code that you cannot modify.
This is all moot of course when we get enum classes with C++0x.
I also tend to wrap my enums in classes.
As signaled by Richard Corden, the benefit of a class is that it is a type in the c++ sense and so you can use it with templates.
I have special toolbox::Enum class for my needs that I specialize for every templates which provides basic functions (mainly: mapping an enum value to a std::string so that I/O are easier to read).
My little template also has the added benefit of really checking for the allowed values. The compiler is kind of lax on checking if the value really is in the enum:
typedef enum { False: 0, True: 2 } boolean;
// The classic enum you don't want to see around your code ;)
int main(int argc, char* argv[])
{
boolean x = static_cast<boolean>(1);
return (x == False || x == True) ? 0 : 1;
} // main
It always bothered me that the compiler will not catch this, since you are left with an enum value that has no sense (and that you won't expect).
Similarly:
typedef enum { Zero: 0, One: 1, Two: 2 } example;
int main(int argc, char* argv[])
{
example y = static_cast<example>(3);
return (y == Zero || y == One || y == Two) ? 0 : 1;
} // main
Once again main will return an error.
The problem is that the compiler will fit the enum in the smallest representation available (here we need 2 bits) and that everything that fits in this representation is considered a valid value.
There is also the problem that sometimes you'd rather have a loop on the possible values instead of a switch so that you don't have to modify all you switches each time you add a value to the enum.
All in all my little helper really ease things for my enums (of course, it adds some overhead) and it is only possible because I nest each enum in its own struct :)