Enum and anonymous enumeration in C ++

1) The following code shows the index of the element enum wednesday . How can I make it print a value instead of an index.

int main() { enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday}; day d=wednesday; cout<<d; return 0; } 

2) In what situation do I prefer anonymous enum over enumeration

+4
source share
7 answers

1). Your code prints the enumeration value, not the index. In your specific example, the index is the same as the value (by default, the first value of the enumeration gets a numeric value of 0, and the rest get sequential incrementing values.

To check:

 int main() { enum day{sunday = 5,monday,tuesday,wednesday,thursday,friday,saturday}; day d=wednesday; cout<<d; // will print 8 (as in 5 + 1 + 1 + 1) return 0; } 

If "print the value" you meant print "medium", you should do the following:

 enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday}; std::ostream& operator << (std::ostream& out, const day d) { static const char *as_strings[] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" }; return out << as_strings[static_cast<int>(d)]; // this only works // for enum values starting from 0 and being consecutive // otherwise you should use a switch(d) and // print each value separately } int main() { day d=wednesday; cout<<d; // will print wednesday return 0; } 

Edit:

2) In what situation do I prefer anonymous enum over enum

You prefer anonymous enumeration when you don't need to pass it as a parameter, but you need to assign meaningful names to constant numeric values:

 my_object record_to_myobject(record& r) { enum {id, value1, value2}; // indexes within record int result_id = r[id]; // much more meaningful than r[0] int result_value1 = r[value1]; int result_value2 = r[value2]; return my_object{result_id, result_value1, result_value2}; } 

It's good to use an anonymous enumeration here, because when you pass a value as an argument, you need an int, not an enumeration type. If you need an enumeration type, then you must give it a name. Otherwise, you will not do it.

+7
source

First, the language does not provide any means of matching the internal enum value for a string. This is actually impossible; consider the following issues:

 enum Numbers { one = 1, two = 2, three = 3, un = 1, deux = 2, trois = 3 }; 

Once you have assigned the enum constant to the enum variable, it contains a numerical value and nothing else. And if the numerical value in the above example is 2, how the system can know whether it should be displayed on two or on deux .

In practice, mapping is useful in many contexts. A while back, I wrote a simple parser to generate display code; it ignores most C ++, will not work in cases where, for example, enum is wrapped in a macro, the code that it generates will not compile if enum is private or protected, and it is undefined which line you get in such cases as above, but I still found it extremely useful.

For the second question: anonymous enumerations are usually used when the only purpose of an enumeration is to generate constants. things like:

 enum { maxSize = 4096 }; 

were widely used before you could provide initialization constant for static member variables. And I often found it convenient to define bit masks using an anonymous enumeration, even when the actual values ​​were on some unsigned type. Such things as:

 enum { offsetMask = 0xF000, offsetShift = 12, NS = 0x100, CWR = 0x80, ECE = 0x40, URG = 0x20, ACK = 0x10, // ... }; uint16_t flags; // ... flags = offset << offsetShift | ACK; 

I do not want to declare my variables for enumeration; they must be exactly 16 bits (according to the TCP specification). In C, I would probably use #define , and in modern C ++ I could use static uint16_t const member variables, but through most of my career in C ++, something like the above would be a normal solution.

+1
source

You need to manually save the array of string "descriptions" of the enumeration values, which is tedious and error prone:

 static const char *daydescs[] = { "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" }; int main() { enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday}; day d=wednesday; cout<< daydescs[(unsigned)d]; return 0; } 
0
source

An enumeration is a number; a string representation (for example, an environment) is a representation of compilation time.

You will need something like:

 const char *dayname[] = {"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}; ... cout << dayname[(unsigned)d]; ... 
0
source

Try the code below:

 int main() { enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday}; String days[7] = {"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}; day d=wednesday; cout<<days[d]; return 0; } 
0
source

1) If you only need an integer value, you can write operator << overload:

 template<typename _stream> _stream& operator << (const day& value) { _stream << static_cast<int>(value); return _stream; } 

Also, consider using an enum class instead of a simple enumeration (unless of course you are allowed to use C ++ 11).

2) I would say that there can be one such case: namespace constants, let's say you have a Person class and you want to have some constants in the class, such as MaxAge or MaxNameLength . But even in such cases, wrapping constraints in something like enum class Settings usually worth it.

0
source

A variant of the type safe for this topic is to use the enum class and use it as a key in std::map

 #include <string> #include <map> #include <iostream> int main() { enum class day { sunday, monday, tuesday, wednesday, thursday, friday, saturday }; std::map<day,std::string> days = { std::make_pair(day::sunday, "Sunday"), std::make_pair(day::monday, "Monday"), std::make_pair(day::tuesday, "Tuesday"), std::make_pair(day::wednesday, "Wednesday"), std::make_pair(day::thursday, "Thursday"), std::make_pair(day::friday, "Friday"), std::make_pair(day::saturday, "Saturday") }; std::cout << days[day::sunday] << std::endl; } 

This means that accessing a map with an integral type will result in a compile-time error.

0
source

Source: https://habr.com/ru/post/1493167/


All Articles