16

I have class like following:

class Car 
{ 
public: 
 Car(); 
 // Some functions and members and <b>enums</b> 
 enum Color
 {
 Red,
 Blue,
 Black
 }; 
 Color getColor();
 void setColor(Color); 
private: 
 Color myColor;
}

I want to:

  1. access to Color values as Color::Red. It is really hardly to understand code when Car::Red is used, when class have a lot enums, subclasses etc.
  2. use type Color as function argument or return value
  3. use variable type Color in switch

I know 3 partial solutions:

  1. Using embedded class Color and enum in it
  2. Using embedded namespace Color and enum in it
  3. Using enum class

1 and 2 solutions solves a Color::Red accession problem, but I can't use functions like Color getColor() and void setColor(Color).

3 solution has a problem: VS2010 doen't support enum class. GCC v.4.1.2 doesn't support it too. I don't know about later versions of gcc.

Yes, I'm working on cross-platform project.
I have found this solution, but it seems ... heavy.
I hope somebody can help me here :)

CharlesB
91.1k29 gold badges203 silver badges228 bronze badges
asked Apr 10, 2012 at 14:46
3
  • 2
    GCC 4.6 (with -std=c++0x) supports enum class, and also allows Color::Red for regular enums. Commented Apr 10, 2012 at 14:48
  • side note, please indent code with 4 spaces instead of using pre/code tags Commented Apr 10, 2012 at 14:51
  • I found than VS2010 has partially support of Strongly typed enums. Commented Apr 10, 2012 at 15:06

3 Answers 3

21

In current C++ (i.e. C++11 and beyond), you can already access enum values like that:

enum Color { Red };
Color c = Color::Red;
Color d = Red;

You can go further and enforce the use of this notation:

enum class Color { Red };
Color c = Color::Red;
// Color d = Red; <-- error now

And on a sidenote, you now define the underlying type, which was previously only possible with hacky code (FORCEDWORD or so anyone?):

enum class Color : char { Red };
answered Apr 10, 2012 at 15:56

6 Comments

You are right, but there is no compilers with full support C++11 features. Yes, GCC 4.6 and 4.7 supports it, but my project must be compiled for Windows too. VS2010 doesn't supports it. May be you know the some patch for it?
You can try MinGW, which is the windows port of GCC. MSVC is closed source and there are no patches.
// Color d = Red; <-- error now is not giving any error at the moment. Also I can acces the values from the enum declared as a global one by typing their names (e.g cout << Red << endl;)
@CătălinaSîrbu: Did you declare it as enum class or just enum?
I declared them just enum
|
7

Name the enum inside the nested class (as example one):

class Car
{
public:
 struct Color
 {
 enum Type
 {
 Red,
 Blue,
 Black
 };
 };
 Color::Type getColor();
 void setColor(Color::Type);
};
answered Apr 10, 2012 at 14:49

5 Comments

You can also mention about C++11 feature enum class.
And use getter and setter of Color in getter and setter of Car?
The Color:: part is not needed here?
@Konrad Woops, fixed my example so now it's needed (since Color is intended to be a nested class).
@iammilind The OP doesn't want to use enum class because it's not uniformly supported across all needed platforms.
5

When I want to do something like this I tend to use a namespace and a typedef outside of th namespace (though usually I'm doing this globally rather than inside a class). Something like this:

namespace colors 
{
 enum Color 
 {
 Red,
 Blue
 ...
 }
}
typedef colors::Color Color;

This way you use the namespace to get at the actual colors, but the Color type itself is still globally accessible:

Color myFav = colors::Red;
answered Apr 10, 2012 at 14:51

8 Comments

VS2010 : error C2059: syntax error : 'namespace' | GCC 4.1.2 : error: expected unqualified-id before 'namespace'
@Jury Probably because you're not allowed to declare namespaces inside classes. Like I said, I usually do this globally. You can always use a nested class if you really want to keep it within a class - the principle's the same.
The typedef isn't really necessary, and I would just put Color as the namespace name and not give the enum a name. I use the namespace method all the time since it's so elegant. Here's some more information about using enums: inphamousdevelopment.wordpress.com/2012/04/02/…
@alex The typedef isn't neccesary, but it's a lot nicer to have a typedef than it is to type colors::Color every time you want to store an enum value somewhere. As for not giving the enum a name - what if you want to use the enum type later on? I guess you're maybe implying you should just use an int, but why throw away type information (and therefore type-safety) like that?
@alex I'd consider that very bad practice. Firstly, you're throwing type safety out the window: normally your compiler could warn you if you try to use a non-Color in place of a Color - but not if you just use an int. Secondly, it just makes things harder to understand for anyone reading the code - how is anyone meant to know at a glance that the function actually accepts values of the Color enum, rather than just any integer from 0 - 65536? Since there's no type safety, anyone could misunderstand the parameter, pass in a value that makes no sense and things would compile fine.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.