Initializing enum class as null - c++

I am wondering if it is possible to initialize an enum class as null. I have written up a short example to illustrate what I am asking about.
I have a header here that defines an enum class called ColorOptions
#ifndef COLORS_HPP
#define COLORS_HPP
enum class ColorOptions
{
RED,
BLUE
};
#endif
and I also have a class that is using this enum class to print colors based on the enum value
#include "Colors.hpp"
#include <iostream>
void printColor(ColorOptions col);
int main()
{
printColor(ColorOptions::RED);
printColor(ColorOptions::BLUE);
}
void printColor(ColorOptions col)
{
switch(col)
{
case ColorOptions::RED:
std::cout << "The color is red" << std::endl;
break;
case ColorOptions::BLUE:
std::cout << "The color is blue" << std::endl;
break;
default:
std::cout << "The color is unknown" << std::endl;
}
}
Is it possible to initalize a ColorOptions as something other than RED or BLUE in this case? I want to reach the default case of the printColor method, but I am not sure if it is possible without adding another type to the ColorOptions enum.

The way to get a value not of the valid enumerations is to use static_cast. That would look like
printColor(static_cast<ColorOptions>(5));
and that will output
The color is unknown
If you can use C++17 then a nice thing you can do would be to change the enum to something like
enum class ColorOptions
{
NONE,
RED,
BLUE
};
and then you can call your function like
printColor({});
which will give you an implicit value of NONE and cause The color is unknown to be print.

Related

Why does this overloaded operator<< work in an unexpected way?

I wanted to create a method to add color to console output that would work in a similar way to std::left and std::setw(). I ended up with the code below, and it works exactly how I want it to. I understand how it works, but I would some clarification on something.
Here is the code:
#include <iostream>
#include <Windows.h>
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
enum class color { blue = FOREGROUND_BLUE, green, cyan, red, purple, yellow, white, bright = FOREGROUND_INTENSITY };
class coutColor {
public:
WORD Color;
coutColor(color colorvalue) : Color((WORD)colorvalue) { }
~coutColor() { SetConsoleTextAttribute(hConsole, (WORD)7); }
};
std::ostream& operator<<(std::ostream& os, const coutColor& colorout) {
SetConsoleTextAttribute(hConsole, colorout.Color);
return os;
}
int main() {
std::cout << coutColor(color::green) << "This text is green!\n";
std::cout << color::red << "This text is red! " << 31 << "\n";
return 0;
}
I understand how coutColor(color::green) works in the cout in main(), but why does just color::red by itself work as well?
I stumbled upon it by accident while testing different things.
How can it take the enum type color as an input, since it's not in the input parameters of the overloaded operator<<?
Why does it do the same thing as inputting coutColor(color::red)?
why does just color::red by itself work as well? ... How can it take the enum type color as an input, since it's not in the input parameters of the overloaded operator<<? Why does it do the same thing as inputting coutColor(color::red)?
It is because coutColor's constructor is not marked as explicit.
When the compiler is looking for a suitable overload of operator<< for the expression std::cout << color::red, it finds your overload in scope and sees that:
coutColor is implicitly constructable from a color value
the operator takes a coutColor object by const reference
So, the compiler is able to create a temporary coutColor object, passing the color value to its constructor, and then pass that object to the operator.
I have seen function(input) : var(input) {} before and I didn't know what it meant.
C++, What does the colon after a constructor mean?

Solution to mimic enum inheritance in cpp

I know that enum inheritance is not possible in c++, but I am looking for specific data structure that simply fit into my case. Suppose I have these two enums:
enum Fruit { apple, orange};
enum Drink { water, milk};
I want a parent for these two that I can use as parameter in this abstract method
void LetsEat(Eatable eatable){}
They are going to be used as simple switches, and basically I want to keep my code clean and type safe. I wonder if I will be forced to use inherited classes that needs to be initialized. It is too much for this simple problem.
Speaking very generally, enums are just dressed up ints.
enum Fruit { apple, orange};
If you look at the compiled code, you will discover that an apple will be represented by the value 0, and an orange will be represented by the value 1.
enum Drink { water, milk};
Same thing here will happen here. water will be represented by value 0, and milk will be represented by value 1. You can begin to see the obvious problem here.
One, a slightly primitive, solution is equivalent to letting a bull loose in the china shop:
enum Drink { water=2, milk=3};
Now you could cook something up where you're passing in a int value and figure out what exactly was passed in, by its value.
But this will likely require plenty of ugly casts, everywhere. The resulting code, if posted to Stackoverflow, will likely to attract downvotes.
The downvotes will be because there are cleaner solutions that are available in modern, post C++17 world. For starters, you can switch to enum classes.
enum class Fruit { apple, orange};
enum class Drink { water, milk};
This gains additional type-safety. It's not as easy, any more, to assign a Fruit to a Drink. Your C++ compiler will bark, very loudly, in many situations where it would raise a warning. Your C++ compiler will help you find even more bugs, in your code. It is true that this will require a little bit more typing. You will always have to specify enumerated values everywhere with full qualification, i.e. Fruit::apple and Drink::water, when in your existing code a mere apple and water will suffice. But a few extra typed characters is a small price to pay for more type-safe code, and for being able to simply declare:
typedef std::variant<Fruit, Drink> Eatable;
and simply do what you always wanted:
void LetsEat(Eatable eatable){}
and everything will work exactly how you wanted it. LetsEat will accept either a Fruit or a Drink as its parameter. It will have to do a little bit more work, to figure out what's in the std::variant, but nobody ever claimed that C++ is easy.
std::variant is one of the more complex templates in the C++ library, and it's not possible to explain how to use it, fully, in a short paragraph or two on Stackoverflow. But this is what's possible, and I'll refer you to your C++ textbook for a complete description of how to use this template.
This sounds like an excellent use case for std::variant.
#include <variant>
#include <iostream>
// Define our enums
enum Fruit { Apple, Orange };
enum Drink { Water, Milk };
// An Eatable is either a Fruit or a Drink
using Eatable = std::variant<Fruit, Drink>;
void letsEat(Eatable eatable) {
// We can use the index() method to figure out which one we have
switch (eatable.index()) {
case 0:
std::cout << "It's a Fruit!" << std::endl;
break;
case 1:
std::cout << "It's a Drink!" << std::endl;
break;
}
}
int main() {
letsEat(Apple);
letsEat(Water);
}
Note that std::variant<Fruit, Drink> is not, strictly speaking, a supertype of Fruit or Drink. Instead, it's a new type altogether but we get implicit conversions from Fruit and Drink to std::variant<Fruit, Drink> via its constructors.
If you're not using C++17, you can use boost::variant from the Boost C++ libraries.
You can use std::variant<T, ...> if you use C++17 or above:
#include <iostream>
#include <variant>
#include <type_traits>
enum Fruit { apple, orange };
enum Drink { water, milk };
using Eatable = std::variant<Fruit, Drink>;
void LetsEat(Eatable const eatable) {
std::visit([] (auto&& v) {
using T = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<T, Fruit>) {
// Now use it like you would use a normal 'Fruit' variable ...
}
if constexpr (std::is_same_v<T, Drink>) {
// Now use it like you would use a normal 'Drink' variable ...
}
}, eatable);
}
int main() {
LetsEat(apple);
}
Alternatively, you could just create a class that is implicitly convertible to either enum type:
class Eatable {
union {
Fruit f;
Drink d;
} u_;
bool has_fruit_;
public:
Eatable(Fruit f) : has_fruit_(true) {
u_.f = f;
};
Eatable(Drink d) : has_fruit_(false) {
u_.d = d;
};
operator Fruit() const {
return u_.f;
}
operator Drink() const {
return u_.d;
}
bool has_fruit() const {
return has_fruit_;
}
};
Then you can use it like this:
void LetsEat(Eatable const eatable) {
if (eatable.has_fruit()) {
Fruit const f = eatable;
switch (f) {
case apple:
std::cout << "Fruit: apple" << std::endl;
break;
case orange:
std::cout << "Fruit: orange" << std::endl;
break;
default: break;
}
} else {
Drink const d = eatable;
switch (d) {
case water:
std::cout << "Drink: water" << std::endl;
break;
case milk:
std::cout << "Drink: milk" << std::endl;
break;
default: break;
}
}
}

Are there any manipulators to print enum values as strings? [duplicate]

This question already has answers here:
enum to string in modern C++11 / C++14 / C++17 and future C++20
(32 answers)
C++: Print out enum value as text
(13 answers)
Closed 3 years ago.
I created an enum names color. And then made a variable background_color of type color. Then assign a enum value, suppose blue. Then I wanted to print background_color using cout. But It prints the corresponding int value of enum member. I wanted to know if there any manipulator which will print the background_color as a string. I know I could use switch cases to get so. But I wished I could acquire this using cout and manipulator.
#include <iostream>
using namespace std;
int main()
{
enum color
{
red,blue,black
};
color background_color=blue;
cout << background_color;
return 0;
}
I expected to print blue as output not 1.A
No there isn't, but you could use a std::map to hold your colors and their names.
#include <iostream>
#include <map>
#include <string>
enum color { red, blue, black };
std::map<color, std::string> color_names{ { red, "red"}, { blue, "blue"}, { black, "black"} };
int main()
{
std::cout << "my favorite color is " << color_names[red] << '\n';
}
You can create a macro that does this.
#define ENUM_TO_STRING(var) (#var)
Then, when you want to use it,
enum Test
{
Test_A,
Test_B
}
int main()
{
std::cout << ENUM_TO_STRING(Test_A) << std::endl;
return 1;
}
This doesn't work for enum stored in a variable though.
I wanted to know if there any manipulator which will print the background_color as a string .
A simple answer: to the best of my knowledge there is no manipulator that will do this for you directly. However, there are plenty of tools and methods to achieve what you want. One had already suggested using an std::map. That is one valid possible way and there are many others each having their own pros and cons. It is up to you to balance out the differences.
Instead of using std::map I chose to use a static const std::array. I also decided to place the enum inside of a struct that contains a constructor and two variables. The type it is and a string for its name. Then I created an overloaded operator<<() to work on my struct for its output.
Here is what my code looks like:
Test.h
#include <array>
#inlucde <iostream>
#include <string>
// must match the size and order of
// the enumeration in the Color Struct
static const std::array<std::string, 8> name {
"Black",
"Red",
"Orange",
"Yellow",
"Green",
"Blue",
"White",
"Invalid"
};
struct Color {
enum Type {
BLACK,
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
WHITE,
INVALID,
} type_;
std::string name_;
explicit Color(Color::Type ty = INVALID) : type_(ty), name_(name[ty] ) {}
};
std::ostream& operator<<(std::ostream& os, const Color& color );
Test.cpp
#include "Test.h"
std::ostream& operator<<(std::ostream& os, const Color& color) {
return os << color.name_;
}
main.cpp
#include "Test.h"
int main() {
Color blank;
Color red(Color::RED);
Color white(Color::WHITE);
Color blue(Color::BLUE);
std::cout << blank << " "
<< red << " "
<< white << " "
<< blue << '\n';
return EXIT_SUCCESS;
}
Output
Invalid Red White Blue
I choose array over map for it has faster access time. Also I chose to make it a const static so that it would only have to be initialized once! These are the pros of my method.
The con is that the array is const and can not be modified, and you can not insert into an array. However because we are dealing with an enumeration, this shouldn't be an issue because you can not add to an enum after its been declared for it is an integral type and not a container.
Another pro to this method is that you do not have to worry about using a switch statement. The only con here is the storage space of two variables, an enum type and a string, but this should not create a large impact for a memory footprint unless if you are storing millions or billions of colors.
The design structure above is good for when you have a limited or a specified amount of objects that you know your application is going to support. Even if you declared 100 predefined colors, this approach is still manageable.
On the other hand if you are storing thousands or tens of thousands of different colors then an std::map might make more sense. In that case, you could declare a static map<unsigned, string> and move it inside of the class, then have a static function that will initialize the map with all of the string names for each of the different object types you will support.

Same identifier in an 2 different enum in same namespace in different files

I am using same namespace in two different files.
In those files i have 2 enum.
I need to use same identifiers in those enum.
Is there a way to do it?
In first file
first.h
...
namespace foo
{
enum direction
{
NONE,
RIGHT
...
}
}
In second file
second.h
...
namespace foo
{
enum reverse
{
NONE,
LEFT,
...
}
}
This is a sample code.
I need to reuse "NONE".
I need code for visual studio 2008.
(Cannot use : enum class)
If you can use C++11, the best way to achieve what you want is to use "strongly typed enums", declared using the enum class keywords, i.e.
enum class direction
{
NONE,
LEFT
};
enum class reverse
{
NONE,
RIGHT
};
In the rest of your code, you then refer to the enumerators as ns::direction::NONE and ns::reverse::NONE (like in C#, if you're familiar with that language).
If you don't have C++11 available, then you can simulate the same thing by declaring an anonymous enum in an inner namespace, for example
namespace direction {
enum {
NONE,
LEFT
};
}
namespace reverse {
enum {
NONE,
RIGHT
};
}
Again, you then refer to direction::NONE and reverse::NONE, so there is no conflict.
#include <iostream>
#include "first.h"
namespace second
{
#include "second.h"
}
using namespace std;
int main()
{
cout << foo::NONE << " " << second::foo::NONE << endl;
return 0;
}
You may use
direction::NONE
and
reverse::NONE
to distinguish the enumerators provided that the enumerations are defined in different scopes. Otherwise the compiler will issue an error of redefinition of an enumerator.
Here is an example
#include <iostream>
enum A { NONE };
namespace N1
{
enum B { NONE = 1 };
}
int main()
{
enum C { NONE = 2 };
std::cout << A::NONE << '\t' << N1::NONE << '\t' << NONE << std::endl;
return 0;
}
The output is
0 1 2
no, you can't reuse the values from one enum to another.
This is probably NOT the right solution, but you can either use explicit enum values, e.g.
enum ...
{
NONE = 0,
...
};
or rely on the compiler starting with 0 and counting up one for each enumeration (assuming no assignment).
However, they are still not the same enum type, and I think you should consider a different solution. It's not entirely clear from your question what you are actually trying to achieve, but it sounds like you are trying to make a "reverse control", where left becomes right and right becomes left, etc. I would suggest having a getter function that does something like this:
direction GetDirection()
{
if (reverse)
{
switch(curDirection)
{
case LEFT:
return RIGHT;
case RIGHT:
return LEFT;
... deal with other directions that need reversing ...
}
}
return curDirection;
}
Another option is to implement two classes, where one does a "reverse switch", and the other just returns the current direction without reversing.

correct way to refer enum items of `boost::date_time`

#include "boost/date_time/gregorian/gregorian.hpp"
int main()
{
boost::gregorian::greg_weekday dWeek(boost::date_time::Wednesday);
//Code One
// warning C4482: nonstandard extension used: enum 'boost::date_time::weekdays' used in qualified name
if (dWeek.as_enum()==boost::gregorian::greg_weekday::weekday_enum::Wednesday)
{
std::cout << "Today is Wednesday" << std::endl;
}
//class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep {
//public:
// typedef boost::date_time::weekdays weekday_enum;
//Code Two
if (dWeek.as_enum()==boost::date_time::Wednesday)
{
std::cout << "Today is Wednesday" << std::endl;
}
}
Question> I have seen tons of code that use Code One to do the comparison of boost::date_time. Based on C++ standard, the usage of the enum is incorrect. I have provided a solution as Code Two.
Can someone give me quick look and see whether it real is CORRECT way to do comparison?
Thank you
EDIT: correction
use
boost::date_time::Wednesday
I didn't look at what type as_enum() returned. Fixed it, compiles & works (on MSVC2k10, Boost 1.48.0 self-built)
EDIT2: You'll find it buried away inside boost/date_time/gregorian/greg_facet.hpp.
namespace boost{
namespace gregorian{
typedef boost::date_time::weekdays weekday_enum;
}
}
Anyway the relevant part for the rest of the info is that there's a boost::date_time::weekdays::Wednesday, but we take out weekdays.
Enums are basically like:
enum foo { bar = 1, barre = 2, barred = 3 };
// Is sort-of the same as
typedef static const int foo;
foo bar = 1;
foo barre = 2;
foo barred = 3;
foo is not a namespace, nor is it a struct, or anything like that, it is more of a typename.
I know it's not exactly the same, but it may as well be for the purposes of using them. Using the weekday_enum qualifier inside a type like that is basically giving the compiler a tiny bit of garbage to parse, it's like saying:
typedef int foo;
struct S {
static foo var;
} p;
p.foo::var = 4; // Does this make sense? Nope...