"using" directive for declarator of scoped enum? [duplicate] - c++

I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.

So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.

So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}

You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.

Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};

I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}

Related

Pulling C++ Enum Class Members Into the Global Namespace

Is there a using directive that imports the members of an enum class directly into the global namespace of a compilation unit?
We have:
enum Lexeme {....lots of names...};
bool Matches(int lookAhead, Lexeme lxm);
This is risky because users frequently forget that the first argument of Matches means "matches either" and write:
if (Matches(ADD,SUB)) ...
The C++ compiler is perfectly happy taking ADD as an int.
So I tried making Lexeme an enum class:
enum class Lexeme { ...}
This catches the error. But now my problem is that all the code that uses Lexeme constants must write the enum class name:
if (Matches(Lexeme::ADD,Lexeme::SUB)) ...
Is there a using directive, or another trick, to pull all of the Lexeme::* names into the current scope? Note, most tokens are used in a class (I get that properly qualifying the constants is one of the safety mechanisms of enum class).
Perhaps a better plan is to change Matches to MatchesAt, or something, to avoid the problem? But I wanted to know the rules for C++ and C++XX, at least.
What I tried:
This is related, but doesn't address the required enum class prefixes.
I also tried something like using foo::bar::Lexeme; but alas to no avail.
You can make an integer wrapper class not convertible to anything else and make some constants out of it.
struct Lexeme
{
private: int m_value;
public: explicit constexpr Lexeme(int value) noexcept
: m_value{value}
{}
};
inline constexpr Lexeme const ADD{1};
inline constexpr Lexeme const SUB{2};
It would probably be a good idea to overload some operators for this class, at least equality and less than.
On a different note, a way to avoid writing Lexeme:: every time would be just to create a shorter alias:
enum class Lexeme { /* lotsa names */ };
using L = Lexeme;
if (Matches(3, L::SUB)) //...
This works well if there is only one or two files where these values are used extensively, and other uses are sparse. I have just had to use a similar solution where I had a Parameter class that read things from XML. I have a enum class ElementType { INTEGER, BOOLEAN, /* etc*/ } and a parsing infrastructure. Within the parser file, I have:
using ET = ElementType;
template<ET et>
struct parser;
// Specializations for each ElementType
template<>
struct parser<ET::INTEGER> {
using type = int;
int parseSingle(const string& s) // ...
}
While outside this file I just have a few usages of ElementType::* constants and I use the full name of the enum class. Should this become too much of a burden, nothing prevents me from ading that alias to a different file.

Is is possible to make scoped enum identifiers driectly accessible in C++? [duplicate]

I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.
So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.
So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}
You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.
Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};
I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}

Typedef to surrounding type in C++

Is there a way to build a typedef inside a type declaration to the declared (surrounding) type itself without stating the type's name?
Example:
class X
{
public:
typedef <fill in magic here> MyType;
//...
};
Background:
This seems silly on the first look. I need this because I build compile-time-reflection of my data classes using macros.
So there is a macro inserted into the declaration of the data class which needs to deal with the type it is inserted into.
So far I found working solutions for MSVC and g++ which both rely on what I think are flaws in the implementation. So they may not work on a newer version.
Clang does not "eat" either of these solutions.
My current solution for MSVC defines a method and then takes it's address only by it's name and calls a small helper that "returns" the type of it's class. (Clang and g++ expect the full name of the method including it's class name).
My current solution for g++ defines a static method with return type std::remove_reference(decltype(*this)). (Clang and MSVC do not allow this in the static context).
I would absolutely prefer a standard conform solution but a special solution for clang would also be ok for the moment.
If nothing works I have to pass the class' name to the macro but I try to avoid this since I already have plenty of code using the macro.
EDIT: Adding a sample on how the reflection works (which may clarify what I need):
class X : public Y
{
public:
//.. constructor and such stuff...
int a;
double b;
std::string c;
CLASSHEAD(Y)
FIELD(a)
FIELD(b)
FIELD(c)
CLASSFOOT
};
CLASSHEAD is the macro that should define typedef. It is a VAR_ARGS macro where the arguments receive the base classes. As said: It is possible to give it the class' name as it's first argument (resulting in CLASSHEAD(X, Y) in the example). But I nearly cannot imagine that there is no solution to such a "simply" task as typedef'ing the surrounding type...
This doesn't exactly meet your specification, but I think its pretty close:
class X
{
//Stuff...
//Use Macros to add:
struct MyType;
//Use class closing macro to insert variable between class-ending brace and semicolon
} TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType
{
typedef decltype(TYPE_VAR) V;
};
Then access X's type using
X::MyType::V
For example, a simplified CLASSFOOT might look like this:
#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V;
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT
Is this good enough for your purposes?
Since you are already using macros, you could use this solution https://stackoverflow.com/a/21143997/2173029
#define CLASS_WITH_MY_TYPE(ClassName) \
class ClassName \
{ \
using MyType = ClassName;
And then use like
CLASS_WITH_MY_TYPE(X)
public:
struct Y
{
using T = MyType;
};
};
static_assert(std::is_same<X, typename X::Y::T>::value, "");
Marked as community wiki since #Chris mentioned the link and the original answer was posted by #Bartek Banachewicz
Nohting works so using the class Name in the macro is the only working solution

Equivalent of "using namespace X" for scoped enumerations?

I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.
So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.
So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}
You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.
Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};
I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}

What is the difference between declaring an enum with and without 'typedef'?

The standard way of declaring an enum in C++ seems to be:
enum <identifier> { <list_of_elements> };
However, I have already seen some declarations like:
typedef enum { <list_of_elements> } <identifier>;
What is the difference between them, if it exists? Which one is correct?
C compatability.
In C, union, struct and enum types have to be used with the appropriate keyword before them:
enum x { ... };
enum x var;
In C++, this is not necessary:
enum x { ... };
x var;
So in C, lazy programmers often use typedef to avoid repeating themselves:
typedef enum x { ... } x;
x var;
I believe the difference is that in standard C if you use
enum <identifier> { list }
You would have to call it using
enum <identifier> <var>;
Where as with the typedef around it you could call it using just
<identifier> <var>;
However, I don't think it would matter in C++
Similar to what #Chris Lutz said:
In old-C syntax, if you simply declared:
enum myEType { ... };
Then you needed to declare variables as:
enum myEType myVariable;
However, if you use typedef:
typedef enum { ... } myEType;
Then you could skip the enum-keyword when using the type:
myEType myVariable;
C++ and related languages have done away with this restriction, but its still common to see code like this either in a pure C environment, or when written by a C programmer.