c++ switch enum error - c++

I'm making a simple switch function using enums, however i'm getting the error 'ACT' undefined identifier. in AS.cpp. Not sure what i'm doing wrong here...
If you could please help explain why I am getting this error that'd be great. THankyou
//AS.h
#ifndef AS_H
#define AS_H
class AS {
private:
enum class state_region;
public:
int determine_FDI(state_region selected_state_region);
};
#endif
/////////AS.cpp
#include "AS.h"
enum class state_region {ACT};
int AS::determine_FDI(state_region selected_state_region) {
int FDI;
switch (selected_state_region) {
case ACT:
FDI = 100;
break;
}
}

"enum class" introduced in C++11 is also called "scoped enumeration".
This clearly highlights the difference with "enum", enum values are now living in a dedicated scope.
You need to add the scope to your "case" like this:
case state_region::ACT:
instead of
case ACT:
This last line is looking for ACT identifier in your current scope but it fails to find it, hence the error.

First, enum class state_region inside class AS is not defined. See comments:
/////////AS.cpp
#include "AS.h"
// This defines ::state_region in the global scope
//enum class state_region {ACT};
// This is the definition of AS::state_region
enum class AS::state_region {ACT};
Second, the enumerators of enum class are not available in the global scope. You need to use state_region::ACT to access it:
int AS::determine_FDI(state_region selected_state_region) {
int FDI;
switch (selected_state_region) {
case state_region::ACT: // <-- state_region:: required
FDI = 100;
break;
}
}

The following code worked correctly:
/////////AS.cpp
#include "AS.h"
enum class AS::state_region {ACT};
int AS::determine_FDI(state_region selected_state_region) {
int FDI;
switch (selected_state_region) {
case state_region::ACT:
FDI = 100;
break;
}
return 0;
}

With enum class as opposed to traditional enums, the enum values are scoped inside of it, which means you have to use them like this: state_region::ACT. The advantage of having to do this is that now multiple enums can use the same value names.
Also, the way you define state_region in cpp file makes it a new enum in global scope. To properly define the one that you declared inside of the class, use enum class AS::state_region {ACT}; (the same way you define methods and static fields).

Related

How to access c++ enum in C file

I am unable to find same question on this site, hence asking. I want to know how to access enum type from C file which is declared inside a class. Consider following example:
test1.h
class abc
{
public:
enum mode
{
ENTER_MODE = 0,
EXIT_MODE = 1
};
}
test2.h
abc::mode test_mode();
test2.c
abc::mode test_mode()
{
if (some_condition)
{
return abc::ENTER_MODE;
}
else
{
return abc::EXIT_MODE;
}
}
This doesn't compile. Any suggestion ?
Try to avoid using classes with C. Instead, just use structures (structures in C++ support many of the features of classes). In this example code (disregard if my assumption is wrong), there is no need for restricting the scope of the enumeration to within a class.
Ideally, you should save these as .cpp files and compile as C++. What does the compilation error say?
End the class definition with a semicolon and declare as:
enum abc::mode test_mode();
try this one (this one compiles) ok:
class abc
{
public:
enum mode
{
ENTER_MODE = 0,
EXIT_MODE = 1
};
};
enum abc::mode test_mode()
{
bool some_condition=false; // or something
if (some_condition)
{
return abc::ENTER_MODE;
}
return abc::EXIT_MODE;
}

C++ Function receiving an enum as one of its parameters

I am trying to make a function receive an enum as one of its parameters. I had the enum as a global but for some reason my other files couldn't change the enum. so I was wondering how do you set an enum as an argument for a function like,
function(enum AnEnum eee);
or is there a better way to solve the above problem?
Okay a quick rephrasing of my question: I basically have numerous files and I want all of them to have access to my enum and be able to change the state of that enum also the majority of files that should be able to access it are in a class. The way I was attempting to fix this was by passing the enum into the function that needed to access it, I couldn't work out how to go about making a function receive an enum as one of its arguments.
If you want to pass a variable that has a value of one of the enums values, this will do:
enum Ex{
VAL_1 = 0,
VAL_2,
VAL_3
};
void foo(Ex e){
switch(e){
case VAL_1: ... break;
case VAL_2: ... break;
case VAL_3: ... break;
}
}
int main(){
foo(VAL_2);
}
If that's not what you mean, please clarify.
(1) my other files couldn't change the enum
You cannot change enum value as they are constants. I think you meant to change the enum variable value.
(2) how do you set an enum as an argument for a function ?
If you want to change the value of the enum variable then pass it by reference
void function (AnEnum &eee)
{
eee = NEW_VALUE;
}

enum flags with name

I'm going to use enum flags for options to initialize my class. The enum is:
namespace MCXJS
{
enum VARPARAM
{
STATIC = 1,
CONST = 2
}
//other things
}
If I'm right, in this case, to check for STATIC I need to do this:
if (param & MCXJS::VARPARAM::STATIC) //...
I know to do it this way:
if (param & MCXJS::STATIC) //...
i need to delete enum name. But it that really necessary? Cannot I use enum values of named enum without typing its name everywhere?
Huh? You don't need to prefix it with the enumeration name. That's only needed for C++0x enum class scoped enumerations.

standards compliant way to typedef my enums

How can I get rid of the warning, without explicitly scoping the enum properly? The standards-compliant code would be to compare against foo::bar::mUpload (see here), but the explicit scopes are really long and make the darn thing unreadable.
maybe there's another way that doesn't use typedef? i don't want to modify the enum--i didn't write it and its in use elsewhere.
warning C4482: nonstandard extension used: enum 'foo::bar::baz' used in qualified name
namespace foo {
class bar {
enum baz {mUpload = 0, mDownload};
}
}
typedef foo::bar::baz mode_t;
mode_t mode = getMode();
if (mode == mode_t::mUpload) //C4482
{
return uploadthingy();
}
else
{
assert(mode == mode_t::mDownload); //C4482
return downloadthingy();
}
If the enum is defined within a class, the best that you can do is bring the class into your own scope and just use class_name::value or define a typedef of the class. In C++03 the values of an enum are part of the enclosing scope (which in your case is the class). In C++0x/11 you will be able to qualify the values with the enum name:
namespace first { namespace second {
struct enclosing {
enum the_enum { one_value, another };
  }
}}
using first::second::enclosing;
typedef first::second::enclosing the_enclosing;
assert( enclosing::one_value != the_enclosing::another );
In the future, your usage will be correct (C++11):
typedef first::second::enclosing::the_enum my_enum;
assert( my_enum::one_value != my_enum::another );
You can enclose your enum into a namespace, and then use a using statement on that namespace.
This obviously only works for enum's outside of class scope.
In your case I don't see why don't you refer to it as bar::mUpload (after using namespace foo, or using foo::bar)
You can use a typedef for foo::bar:
typedef foo::bar fb;
//...
fb::baz m = fb::mUpload;
Or are you looking for something different?

namespaces for enum types - best practices

Often, one needs several enumerated types together. Sometimes, one has a name clash. Two solutions to this come to mind: use a namespace, or use 'larger' enum element names. Still, the namespace solution has two possible implementations: a dummy class with nested enum, or a full blown namespace.
I'm looking for pros and cons of all three approaches.
Example:
// oft seen hand-crafted name clash solution
enum eColors { cRed, cColorBlue, cGreen, cYellow, cColorsEnd };
enum eFeelings { cAngry, cFeelingBlue, cHappy, cFeelingsEnd };
void setPenColor( const eColors c ) {
switch (c) {
default: assert(false);
break; case cRed: //...
break; case cColorBlue: //...
//...
}
}
// (ab)using a class as a namespace
class Colors { enum e { cRed, cBlue, cGreen, cYellow, cEnd }; };
class Feelings { enum e { cAngry, cBlue, cHappy, cEnd }; };
void setPenColor( const Colors::e c ) {
switch (c) {
default: assert(false);
break; case Colors::cRed: //...
break; case Colors::cBlue: //...
//...
}
}
// a real namespace?
namespace Colors { enum e { cRed, cBlue, cGreen, cYellow, cEnd }; };
namespace Feelings { enum e { cAngry, cBlue, cHappy, cEnd }; };
void setPenColor( const Colors::e c ) {
switch (c) {
default: assert(false);
break; case Colors::cRed: //...
break; case Colors::cBlue: //...
//...
}
}
Original C++03 answer:
The benefit from a namespace (over a class) is that you can use using declarations when you want.
The problem with using a namespace is that namespaces can be expanded elsewhere in the code. In a large project, you would not be guaranteed that two distinct enums don't both think they are called eFeelings
For simpler-looking code, I use a struct, as you presumably want the contents to be public.
If you're doing any of these practices, you are ahead of the curve and probably don't need to scrutinize this further.
Newer, C++11 advice:
If you are using C++11 or later, enum class will implicitly scope the enum values within the enum's name.
With enum class you will lose implicit conversions and comparisons to integer types, but in practice that may help you discover ambiguous or buggy code.
FYI In C++0x there is a new syntax for cases like what you mentioned (see C++0x wiki page)
enum class eColors { ... };
enum class eFeelings { ... };
I've hybridized the preceding answers to something like this: (EDIT: This is only useful for pre- C++11. If you are using C++11, use enum class)
I've got one big header file that contains all my project enums, because these enums are shared between worker classes and it doesn't make sense to put the enums in the worker classes themselves.
The struct avoids the public: syntactic sugar, and the typedef lets you actually declare variables of these enums within other worker classes.
I don't think using a namespace helps at all. Maybe this is because I'm a C# programmer, and there you have to use the enum type name when referring the values, so I'm used to it.
struct KeySource {
typedef enum {
None,
Efuse,
Bbram
} Type;
};
struct Checksum {
typedef enum {
None =0,
MD5 = 1,
SHA1 = 2,
SHA2 = 3
} Type;
};
struct Encryption {
typedef enum {
Undetermined,
None,
AES
} Type;
};
struct File {
typedef enum {
Unknown = 0,
MCS,
MEM,
BIN,
HEX
} Type;
};
...
class Worker {
File::Type fileType;
void DoIt() {
switch(fileType) {
case File::MCS: ... ;
case File::MEM: ... ;
case File::HEX: ... ;
}
}
I would definitely avoid using a class for this; use a namespace instead. The question boils down to whether to use a namespace or to use unique ids for the enum values. Personally, I'd use a namespace so that my ids could be shorter and hopefully more self-explanatory. Then application code could use a 'using namespace' directive and make everything more readable.
From your example above:
using namespace Colors;
void setPenColor( const e c ) {
switch (c) {
default: assert(false);
break; case cRed: //...
break; case cBlue: //...
//...
}
}
Advantage of using a class is that you can build a full-fledged class on top of it.
#include <cassert>
class Color
{
public:
typedef enum
{
Red,
Blue,
Green,
Yellow
} enum_type;
private:
enum_type _val;
public:
Color(enum_type val = Blue)
: _val(val)
{
assert(val <= Yellow);
}
operator enum_type() const
{
return _val;
}
};
void SetPenColor(const Color c)
{
switch (c)
{
case Color::Red:
// ...
break;
}
}
As the above example shows, by using a class you can:
prohibit (sadly, not compile-time) C++ from allowing a cast from invalid value,
set a (non-zero) default for newly-created enums,
add further methods, like for returning a string representation of a choice.
Just note that you need to declare operator enum_type() so that C++ would know how to convert your class into underlying enum. Otherwise, you won't be able to pass the type to a switch statement.
An difference between using a class or a namespace is that the class cannot be reopened like a namespace can. This avoids the possibility that the namespace might be abused in the future, but there is also the problem that you cannot add to the set of enumerations either.
A possible benefit for using a class, is that they can be used as template type arguments, which is not the case for namespaces:
class Colors {
public:
enum TYPE {
Red,
Green,
Blue
};
};
template <typename T> void foo (T t) {
typedef typename T::TYPE EnumType;
// ...
}
Personally, I'm not a fan of using, and I prefer the fully qualified names, so I don't really see that as a plus for namespaces. However, this is probably not the most important decision that you'll make in your project!
Since enums are scoped to their enclosing scope, it's probably best to wrap them in something to avoid polluting the global namespace and to help avoid name collisions. I prefer a namespace to class simply because namespace feels like a bag of holding, whereas class feels like a robust object (cf. the struct vs. class debate). A possible benefit to a namespace is that it can be extended later - useful if you're dealing with third-party code that you cannot modify.
This is all moot of course when we get enum classes with C++0x.
I also tend to wrap my enums in classes.
As signaled by Richard Corden, the benefit of a class is that it is a type in the c++ sense and so you can use it with templates.
I have special toolbox::Enum class for my needs that I specialize for every templates which provides basic functions (mainly: mapping an enum value to a std::string so that I/O are easier to read).
My little template also has the added benefit of really checking for the allowed values. The compiler is kind of lax on checking if the value really is in the enum:
typedef enum { False: 0, True: 2 } boolean;
// The classic enum you don't want to see around your code ;)
int main(int argc, char* argv[])
{
boolean x = static_cast<boolean>(1);
return (x == False || x == True) ? 0 : 1;
} // main
It always bothered me that the compiler will not catch this, since you are left with an enum value that has no sense (and that you won't expect).
Similarly:
typedef enum { Zero: 0, One: 1, Two: 2 } example;
int main(int argc, char* argv[])
{
example y = static_cast<example>(3);
return (y == Zero || y == One || y == Two) ? 0 : 1;
} // main
Once again main will return an error.
The problem is that the compiler will fit the enum in the smallest representation available (here we need 2 bits) and that everything that fits in this representation is considered a valid value.
There is also the problem that sometimes you'd rather have a loop on the possible values instead of a switch so that you don't have to modify all you switches each time you add a value to the enum.
All in all my little helper really ease things for my enums (of course, it adds some overhead) and it is only possible because I nest each enum in its own struct :)