Program-defined types: Enumeration (Part 1)
Unscoped enumerations
Although I am no professional, I have a fundamental understanding of the typical data types of C++: int, double, string and whatnot. But after a while, those started to get repetitive and boring. And that's when our today protagonist comes in. With an example, you'll get exactly what I'm talking about.
// Define a new unscoped enumeration named Family
enum Family
{
// Here are the enumerators
// These symbolic constants define all the possible values this type can hold
// Each enumerator is separated by a comma, not a semicolon
dad,
mom,
uglysis, // trailing comma optional but recommended
}; // the enum definition must end with a semicolon
int main()
{ // Define a few variables of enumerated type Color
Family inTheKitchen { mom }; // mom is in the kitchen
Family watching TV { dad }; // dad is watching TV
Family ugly { uglysis }; // uglysis is ugly
Family noChance { prettysis }; // error: prettysis is not an enumerator of Family
return 0;
}
Without needing any prior knowledge, you can understand the program easily. To create such programs, some knowledge are required, of course. But you can imagine, at least that's what I would imagine, what programmers do. By simplying the codes using unclosed enumerations, with minimal usage of comments, you and your collegues (if you ever graduate and make it) are gonna have a better time coding.
And something more interesting is that each enumerator are assigned a value that's continous from the previous enumerator, with 0 as the first if no assigning or done. Also, if two enumerators are assigned the same number, they're interchangeable, though not recommended.
#include <iostream>
enum Color
{
black, // assigned 0
red, // assigned 1
blue = 5, // assigned 5
green, // assigned 6
white, // assigned 7
cyan = -2, // assigned -2
yellow, // assigned -1
magenta, // assigned 0
};
int main()
{
Color shirt{ blue }; // This actually stores the integral value 5
return 0;
}
Even though not learning everything about it yet, I have made an attempt to try do what I know and do input/output. Let's just say their are better ways ... but it's simple to understand. You can try to do it yourself by defining an enumerated type with the name Color but this is my attempt.
#include <iostream>
#include <string>
using namespace std;
enum Color
{
red,
green,
blue,
};
int main()
{
Color shirt;
string shirtInput;
cin >> shirtInput;
if (shirtInput == "blue") shirt = blue;
if (shirtInput == "red") shirt = red;
if (shirtInput == "green") shirt = green;
if (shirt == blue)
cout << "Your shirt is blue!";
else
cout << "Your shirt is not blue!";
return 0;
}
And next is an attempt of pure magic to my eyes:
#include <iostream>
enum Color
{
black,
red,
blue,
};
// Teach operator<< how to print a Color
// Consider this magic for now since we haven't explained any of the concepts it uses yet
// std::ostream is the type of std::cout
// The return type and parameter type are references (to prevent copies from being made)!
std::ostream& operator<<(std::ostream& out, Color color)
{
switch (color)
{
case black: return out << "black";
case red: return out << "red";
case blue: return out << "blue";
default: return out << "???";
}
}
int main()
{
Color shirt{ blue };
std::cout << "Your shirt is " << shirt; // **it works!**
return 0;
}
Any Dumbledores out there that can give me some insights before I learn it from Alex (the creator of the website I'm referencing), then please, you are welcomed and I give you my thanks.
REFERENCE
Chapter 10.1-10.2
Top comments (2)
Your code looks mostly fine; though usually you would ALLCAPS unscoped enumerations by convention.
However, unscoped enumerations have pretty much been superceded by scoped enumerations. For instance:
This is due to scoping and strong typing. Unscoped enumerations are unscoped, meaning you end polluting the namespace. (This is also why
using namespace std;
is also not recommended.) In addition, they are implicitly convertable to their underlying type, which can hide bugs.1 Take for instance your above code, but without the operator overload.This is probably not what you want. With a scoped enumeration, the equivelant code would cause a compilation error.
As an aside, did you know you can enable syntax highlighting by putting the language name after the three backticks?
This is sometimes useful, however] ↩
I've just started coding and just found this interesting to start covering about. Next week there should be one on either scoped enumeration (or struct) so I'll get to learn about what you're talking about. And the thing about the syntax highlighting is much appreciated as this is my first blog/post ever on any type of social media. Have a nice day!