constexpr and initialization - c++

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);

Related

How to check data type in C++?

I'm fairly new to C++, I've been mainly using python. I'm trying to check the type of variable of the value stored in the objects I'm working on. I remember that in Python there was a comand isinstance where I could use it as a condition to run certain commands, like if the next value is a string, do A, and if it's an int do B.
Is there a way to quickly check what's the data type on a variable in C++?
Example:
In python I had an array with a math operation, each character in a field
[3,"+",2]
as I read the array I would separate the ints from the strings with the isinstance command
if isinstance(list[0],int):
aux1.append(list[0])
list=list[1:]
else:
if isinstance(lista[0],str):
aux2.append(list[0
list=list[1:]
now in C++ I need to do something similar, but this time each character is in a node from a linked list and again, I need to separate them, ints in a linked list, and strings in another linked list
What you seem to be struggling with is that C++ is a statically and a (relatively) strongly typed language. For a discussion about what each of these terms actually mean i refer to this other question, as it's explained there probably much better than I could.
First of all you should be sure that you actually need to do things the way you're trying currently. Do not try to write Python style code.
That said, there are basically two different approaches with which you can achieve a behavior that's similar to what Python (dynamically typed, duck typing and thus relatively weak typing) allows you to do:
Use C++'s builtin dynamic type mechanisms. Therefore, you need to create a so called polymorphic base class, that is a class that has at least one virtual member function (the destructor also works if you don't have a defined interface - it most often also must be virtual to avoid nasty issues). A short example:
struct Value {
virtual void write_to(std::ostream &) const = 0;
virtual void read_from(std::istream &) = 0;
virtual ~Value() {} // Absolutely required!!!
};
struct Number : public Value {
int data;
void write_to(std::ostream & stream) const {
stream << "<Number " << data << ">";
}
void read_from(std::istream & stream) {
stream >> data; // Not the same format as write_to, shame on me
}
// Implicit destructor is fine
};
struct String : public Value {
std::string data;
void write_to(std::ostream & stream) const {
stream << "<String " << data.size() << " " << data << ">";
}
void read_from(std::istream & stream) {
stream >> data; // Not the same format as write_to, shame on me
}
};
Using this you can now for example store Values whose actual type you can let the user decide:
std::vector<std::unique_ptr<Value>> values;
while (wantsToEnterMoreValues) {
std::string choice = ask("What type of value do you want to enter?");
std::unique_ptr<Value> value;
if (choice == "string") {
value = std::make_unique<String>();
} else if (choice == "number") {
value = std::make_unique<Number>();
} else {
// launch apocalypse
}
value->read_from(std::cin);
values.push_back(value);
}
This is easily extensible to more types. Note that in order to use C++'s builtin dynamic typing you need to go without value semantics, but instead completely use reference semantics, either using real references, or (in most cases where ownership must be transferred, like in above example to the values vector) using pointers.
The dynamic_cast approach works very similar to this, except that you're using runtime type information more explicitly and don't need a unified interface (but have much more work in order to maintain your code).
Use the union language feature. This only has become really possible with C++11, where union members may be non-trivially construable:
enum class Type {
Number, String
};
struct Value {
Type type;
union {
std::string string;
int number;
};
Value(std::string const & s) : type(Type::String), string(s) {}
Value(int n) : type(Type::Number), number(n) {}
Value(Value const & v) : type(v.type) {
switch (type) {
case Type::Number: number = v.number; break;
case Type::String: new (&string) std::string(v.string); break;
default: break; // Launch nuclear missiles
}
}
~Value() {
switch (type) {
case Type::String: string.~std::string(); break;
default: break;
}
}
};
As you can see, this quite a lot of work. With this approach you can use value semantics, but cannot as easily extend your Values to support more types. Moreover, due to using a union, you're going to waste some memory.
Bottom line: You need to implement the behavior on your own, but can do so in exactly the way you want it to behave. For example: You could also implement assignment operators operator=(Value const &) that do implicit type conversions. You can also use the implementations from boost, like boost::any or boost::variant.
I'd like to reference two answers I've written on this site to the very same subject, perhaps they're also helpful for you:
https://stackoverflow.com/a/32926607/1116364
https://stackoverflow.com/a/32041381/1116364
Also some C code which is relevant, because it tries to solve the same issue: https://stackoverflow.com/a/35443434/1116364
Note: All code in this answer is written straight out of memory and not tested. It thus serves only as demonstration of the basic techniques.
Unlike Python, C++ is a strongly typed language. This means that the type of each object is known at compile time.
Having said that, there is a very, very vague analogue that can apply in some circumstances.
If you have a pointer to an object whose class has at least one virtual method, a dynamic_cast will either convert it to a pointer to the requested class, or to a nullptr. This would only work when the most-derived object that's being pointed to includes both classes in its hierarchy, unambiguously.

Searchable Enum-like object with string and int conversion

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.

Why does this C++ code use an anonymous enum rather than a const variable? [duplicate]

What is the purpose of anonymous enum declarations such as:
enum { color = 1 };
Why not just declare int color = 1?
That's a so-called enum trick for declaring a compile-time integer constant. It's advantage is it guarantees that no variable is instantiated and therefore there's no runtime overhead. Most compilers introduce no overhead with integer constants anyway.
Enums don't take up any space and are immutable.
If you used const int color = 1; then you would solve the mutability issue but if someone took the address of color (const int* p = &color;) then space for it would have to be allocated. This may not be a big deal but unless you explicitly want people to be able to take the address of color you might as well prevent it.
Also when declaring a constant field in a class then it will have to be static const (not true for modern C++) and not all compilers support inline initialization of static const members.
Disclaimer: This answer should not be taken as advice to use enum for all numeric constants. You should do what you (or your co-workers) think is more readable. The answer just lists some reasons one might prefer to use an enum.
If this is old code, then enum might have been used for the "enum hack".
You can learn more about the "enum hack", for example, in this link: enum hack
In short: this allows defining the value once, just like #define or defining a variable, but unlike #define - here the compiler makes sure that the value is a number (int, r-value) and prevents you from doing all kinds of mischief that you can do with the precompiler's simple "search and replace", and unlike defining a variable - never takes up space under any compiler or configuration, and prevents changes to it (even const variables can sometimes be changed if you try hard enough).
(1) int color = 1;
color is changeable (accidently).
(2) enum { color = 1 };
color cannot be changed.
The other option for enum is,
const int color = 1; // 'color' is unmutable
Both enum and const int offer exactly same concept; it's a matter of choice. With regards to popular belief that enums save space, IMO there is no memory constraint related to that, compiler are smart enough to optimize const int when needed.
[Note: If someone tries to use const_cast<> on a const int; it will result in undefined behavior (which is bad). However, the same is not possible for enum. So my personal favorite is enum]
One use of this is when you're doing template metaprogramming, because enum objects are not lvalues, while static const members are. It also used to be a common workaround for compilers that didn't let you initialize static integral constants in the class definition. This is explained in another question.
When you use
enum {color = 1}
you're not using any memory it's like
#define color 1
If you declare a variable
int color=1
Then you're taking up memory for a value that's not to be changed.
Answer
Readability and performance.
Details are describbed as notes to examples below.
Use cases
Personal example
In Unreal Engine 4 (C++ game engine), I have following property (engine exposed member variable):
/// Floor Slope.
UPROPERTY
(
Category = "Movement",
VisibleInstanceOnly,
BlueprintGetter = "BP_GetFloorSlope",
BlueprintReadOnly,
meta =
(
ConsoleVariable = "Movement.FloorSlope",
DisplayName = "Floor Slope",
ExposeOnSpawn = true,
NoAutoLoad
)
)
float FloorSlope = -1.f;
This is a value of floor slope player is standing on (value ∈ [0; 90)°), if any.
Because of engine limitations, it cannot be neither std::optional nor TOptional.
I've came up with a solution to add another self explainable variable bIsOnFloor.
bool bIsOnFloor = false;
My C++ only internal setter for FloorSlope takes the following form:
void UMovement::SetFloorSlope(const float& FloorSlope) noexcept
contract [[expects audit: FloorSlope >= 0._deg && FloorSlope < 90._deg]]
{
this->bIsOnFloor = true;
this->FloorSlope = FloorSlope;
AUI::UI->Debug->FloorSlope = FString::Printf(L"Floor Slope: %2.0f", FloorSlope);
};
Adding special case where FloorSlope parameter would take argument of -1.f would be hard to guess and not user friendly.
Instead, I'd rather create False enum field:
enum { False };
This way, I can simply overload SetFloorSlope function that takes intuitive False instead of -1.f.
void UMovement::SetFloorSlope([[maybe_unused]] const decltype(False)&) noexcept
{
this->bIsOnFloor = false;
this->FloorSlope = -1.f;
AUI::UI->Debug->FloorSlope = L"Floor Slope: —";
};
When a player character hits a floor upon applying gravity to it on tick, I simply call:
SetFloorSlope(FloorSlope);
… where FloorSlope is a float value ∈ [0; 90)°.
Otherwise (if it does not hits a floor), I call:
SetFloorSlope(False);
This form (as opposed to passing -1.f) is much more readable, and self explanatory.
Engine example
Another example may be to prevent or force initialization.
Mentioned above Unreal Engine 4 commonly uses FHitResult struct containing information about one hit of a trace, such as point of impact and surface normal at that point.
This complex struct calls Init method by default, setting some values to certain member variables. This can be forced or prevented (public docs: FHitResult #constructor):
FHitResult()
{
Init();
}
explicit FHitResult(float InTime)
{
Init();
Time = InTime;
}
explicit FHitResult(EForceInit InInit)
{
Init();
}
explicit FHitResult(ENoInit NoInit)
{
}
Epic Games defines such enums similiar, but adds redundant enum names:
enum EForceInit
{
ForceInit,
ForceInitToZero
};
enum ENoInit {NoInit};
Passing NoInit to the constructor of FHitResult prevents initialization, what can lead to performance gain by not initializing values that will be initialized elsewhere.
Community example
FHitResult(NoInit) usage in DamirH's post on Comprehensive GameplayAbilities Analysis Series:
//A struct for temporary holding of actors (and transforms) of actors that we hit
//that don't have an ASC. Used for environment impact GameplayCues.
struct FNonAbilityTarget
{
FGameplayTagContainer CueContainer;
TWeakObjectPtr<AActor> TargetActor;
FHitResult TargetHitResult;
bool bHasHitResult;
public:
FNonAbilityTarget()
: CueContainer(FGameplayTagContainer())
, TargetActor(nullptr)
, TargetHitResult(FHitResult(ENoInit::NoInit))
, bHasHitResult(false)
{
}
// (…)
I dont see it mentioned, another use is to scope your constants. I currently work on code that was written using Visual Studio 2005, and it is now ported to android - g++. In VS2005 you could have code like this enum MyOpts { OPT1 = 1 }; and use it as MyOpts::OPT1 - and compiler did not complain about it, even though it is not valid. g++ reports such code as error, so one solution is to use anonymous enum as follows: struct MyOpts { enum {OPT1 =1}; };, and now both compilers are happy.

C++ : nameable objects belonging to an instance of a class, and stored in it

I am trying to make it possible for a programmer (who uses my library) to create nameable instances of type X that are stored inside an instance of class C (or at least are exclusive to that instance).
These are the only two (ugly) solutions I have managed to come up with (needless to say, I am just picking up C++)
1)
class C
{
public:
class XofC
{
public:
XofC() = delete;
XofC(C& mom)
{
mom.Xlist.emplace_front();
ref = Xlist.front();
}
X& access()
{
return ref;
}
private:
X& ref;
};
//etc
private:
std::forward_list<X> Xlist;
friend class XofC;
//etc
}
Problem:
Having to pass everywhere XofC instances.
2)
class C
{
public:
void newX(std::string);
X& getX(std::string);
//etc.
private:
/*possible run-time mapping implementation
std::vector<X> Xvec;
std::unordered_map<std::string, decltype(Xvec.size())> NameMap;
*/
//etc
}
Problem:
This does the job, but since all names of X (std::string) are known at compilation, the overhead of using run-time std::unordered_map<std::string, decltype(Xvec.size())> kind-of bugs me for something this simple.
Possible(?) solution: compile-time replacing of std::string with automatic index (int). Then I could use:
class C
{
public:
void newX(int); //int: unique index calculated at compile time from std::string
X& getX(int); //int: unique index calculated at compile time from std::string
//etc.
private:
std::vector<X> Xvec;
}
Questions:
Is there a 3)?
Is a compile time solution possible for 2)?
This is the real-life situation: I was starting my first C++ "project" and I thought I could use the practice and utility from an awesome user-friendly, simple and fast argument management library. I plan to make an ArgMan class which can parse the argV based on some specified switches. Switches would be named by the programmer descriptively and the trigger strings be specified (e.g. a switch named recurse could have "-r" and "-recursive" as triggers). When necessary, you should be easily able to get the setting of the switch. Implementation detail: ArgMan would have a std::unordered_map<std::string/*a trigger*/, ??/*something linking to the switch to set on*/>. This ensures an almost linear parse of argV relative to argC. How should I approach this?
You could 'abuse' non-type template arguments to get compiletime named instances:
Live on Coliru
Assume we have a data class X:
#include <string>
struct X
{
int has_some_properties;
std::string data;
};
Now, for our named instances, we define some name constants. The trick is, to give them external linkage, so we can use the address as a non-type template argument.
// define some character arrays **with external linkage**
namespace Names
{
extern const char Vanilla[] = "Vanilla";
extern const char Banana [] = "Banana";
extern const char Coconut[] = "Coconut";
extern const char Shoarma[] = "Shoarma";
}
Now, we make a NamedX wrapper that takes a const char* non-type template argument. The wrapper holds a static instance of X (the value).
// now we can "adorn" a `namedX` with the name constants (above)
template <const char* Name>
struct NamedX
{
static X value;
};
template <const char* Name> X NamedX<Name>::value;
Now you can use it like this:
int main()
{
X& vanilla = NamedX<Names::Vanilla>::value;
vanilla = { 42, "Woot!" };
return vanilla.has_some_properties;
}
Note that due to the fact that the template arguments are addresses, no actual string comparison is done. You cannot, e.g. use
X& vanilla = NamedX<"Vanilla">::value;
becuase "Vanilla" is a prvalue without external linkage. So, in fact you could do without some of the complexity and use tag structs instead: Live on Coliru
While Neil's solution did what I asked for, it was too gimmicky to use in my library. Also, sehe's trick is surely useful, but, if I understood correctly, but doesn't seem related to my question. I have decided to emulate the desired behavior using method 1), here is a less broken attempt at it:
class C
{
private:
class X
{
//std::string member;
//etc
};
public:
class XofC
{
public:
XofC(C & _mom) : mom(_mom)
{
mom.Xlist.emplace_front();
tehX = &(Xlist.front());
}
X & get(maybe)
{
if (&maybe != &mom) throw std::/*etc*/;
return &tehX;
}
private:
X * tehX;
C & mom;
};
private:
//etc
std::forward_list<X> Xlist;
friend class XofC;
//etc
};
Usage:
C foo;
bar = C::XofC(foo); //acts like an instance of X, but stored in C, but you have to use:
bar.get(foo)/*reference to the actual X*/.member = "_1_";
Of course, the downside is you have to make sure you pass bar everywhere you need it, but works decently.
This is how it looks like in my tiny argument manager library:
https://raw.github.com/vuplea/arg_manager.h/master/arg_manager.h

Extending enums in C++?

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};