Access enum values in C++98 and C++11
Domanda
I have a set of enum values defined in the "Foo" class (below).
namespace Fii
{
class Foo
{
struct Bar
{
enum Baz
{
BAZ1,
BAZ2,
BAZ3
};
};
};
};
I am using a struct to reduce the scope of Baz enum values as well as show there are a group of related values.
My objective is to assign a value from an enum type to a variable. Using the class definition above, one can do this:
Fii::Foo::Bar::Baz myValue = Fii::Foo::Bar::BAZ1 (Works in both C++98 and C++11)
However, I feel that:
- At first glance, myValue seems to be initialized as a Fii::Foo::Bar but this is just because enum are a hack to group related constants in the parent (Bar in this case)
To improve readiness, I I re-factored the code to:
namespace Fii
{
class Foo
{
enum Baz
{
BAZ1,
BAZ2,
BAZ3
};
};
};
Using this new class definition, one can do this:
Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 (Works in C++11 only)
Fii::Foo::Baz myValue = Fii::Foo::BAZ1 (Should work on C++98 and C++11 - not tested)
Q1) Why is Fii::Foo::Bar::Baz myValue = Fii::Foo::Baz::BAZ1 only working on C++11 ?
Q2) In C++98, is there a way to write Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 ? You are allowed to make any changes you like in the class definition.
Environment: - Clang compiler with C++11 support - Xcode 4 - Mac OS OS 10.8
Soluzione
juanchopanza's answer's valid for Q1...
Q2: In C++98, is there a way to write Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 ? You are allowed to make any changes you like in the class definition.
Something like:
namespace Fii
{
class Foo
{
class Baz
{
public:
enum E { BAZ1, BAZ2, BAZ3 };
Baz(E e) : e_(e) { }
operator const E() const { return e_; }
private:
E e_;
};
};
}
Explanation: for Fii::Foo::Baz::BAZ1
to be a valid reference to an enumeration in C++03, Baz
must be a namespace
or class
/struct
/union
. But, we're trying to make it seem as if Baz itself is the enumeration type, with BAZ1 being one of the available values. To do that, we must make Baz a user-defined-type (a class/struct) capable of storing any of the enumerations declared within its scope. Therefore, we add a data member to record the current value, a constructor to set the value, an operator to expose the enumeration value implicitly so you'd don't need to code explicit references to e_
everywhere in the code using Baz
objects or call some get() const
function.
Altri suggerimenti
C++11 adds class enums. It also adds a new way of accessing old-style enum values, which is what you are seeing here.
enum Foo { FOO1, FOO2, FOO3 }; // old-style enum
Foo f1 = Foo::FOO1; // OK in C++11, error in C++98.
Foo f2 = FOO1; // OK in C++98 and C++11 (for backward compatibility)