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

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;
}

Related

Can two enums not have a member of similar name?

I have a situation where I need two enums to hold one member of the same name. My code is in C++, Using IAR Embeddedj Workbench IDE. The code snippet is as follows:
enum Port_e : uint32_t
{
PortA = 0,
PortB,
PortC,
PortD,
PortE,
PortF,
PortG,
PortH,
PortI,
PortJ,
PortK,
NONE
};
enum Pin_e : uint32_t
{
Pin0 = 0, Pin1, Pin2, Pin3, Pin4, Pin5, Pin6, Pin7,
Pin8, Pin9, Pin10, Pin11, Pin12, Pin13, Pin14, Pin15,NONE
};
If you notice here both enums have the last member as NONE.
This code does not compile. Gives Error as NONE is already defined.
Is there any way to make it build while keeping the name as it is?
I also do not want to change the type to "enum class" as it will break the rest of my application code.
Is there any way to make it build while keeping name as it is?
Not without changes. If you wrap Port_e and Pin_e in a namespace or class you can resolve the name collision, but that would still alter the way the enums are used.
I also do not want to change the type to "enum class" as it will break the rest of my application code.
I strongly suggest you to do that anyway, and take the time to fix your application code. enum class was designed exactly to solve this problem.
You can use class enums or nest your enums in appropriate classes or namespaces.
#include <iostream>
enum class A :uint32_t { One, Two, Three };
enum class B :uint32_t { One, Two, Three };
int main()
{
std::cout << int(A::One) << std::endl;
}
Identifiers of enumeration are names of integral constants belonging to namespace enum is declared in. Class enums changed this situation, but you cant cast from and to them implicitly. Any other approach eventually would cause ODR breakage if you would use simple enogh names. In your code it leads to ambiguity: is NONE equal to 13? Or to 16?

How to pass an enum to a method without passing it as an integer

I Have an enum which contains 3 different values
enum
{
inputValidation_Zipcode,
inputValidation_String,
inputValidation_Number
} InputValidation;
I am trying to pass one of these three enum values to a method, and have tried the following.
bool methodName(enum InputValidation inputenum)
bool methodName(InputValidation inputenum)
and ofc
bool methodName(int inpoutenum)
(All three called as methodName(InputValidation_Number) )
I know the last one will "work" but allows ALL integers as arguments. How can I Write a method to only accept the inputValidation values?
Your enum definition is wrong, it should be:
enum /*class*/ InputValidation
{
inputValidation_Zipcode,
inputValidation_String,
inputValidation_Number
};
Then you might use:
bool methodName(InputValidation inputenum);
Give scoped enum a try by adding class as follows:
enum class InputValidation
{
inputValidation_Zipcode,
inputValidation_String,
inputValidation_Number
};
For more information:
https://en.cppreference.com/w/cpp/language/enum

c++ switch enum error

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).

Is it possible to pass an entire enum set as a parameter?

I am aware that you can use part of an enum as a parameter for a function. The question I have is can you use an entire enum as a parameter?
For the enum:
enum exampleEnum {ONE,TWO,THREE}
by partial enum I am referring to:
function example(exampleEnum value){}
function example(ONE);
by entire enum is:
function example(enum value){}
function example(exampleEnum);
I guess what I am asking is can I pass an enum like you pass an array. At least that is what I think I am asking.
edit
The effect I am trying to achieve is to share an enum across multiple classes and subclasses without redefining it in every class/subclass I wish to use it in. I want these values to be passed instead of using some form a global variable.
edit of the edit
To be more specific... I am using the enum values as a form of associative array.
enum attribute{STR,DEX,CON,INT,WIS,CHA};
short int charAttributes[6];
charAttributes[STR] = sumValue;
charAttributes[DEX] = sumValue;
charAttributes[CON] = sumValue;
charAttributes[INT] = sumValue;
charAttributes[WIS] = sumValue;
charAttributes[CHA] = sumValue;
What I am wanting is to pass the enumeration in its entirety name, values, everything to be passed as a parameter. I am wanting to pass the enumeration to keep the enumeration names and values to continue using them as such.
exampleEnum is a type, not a value.
C++ way to pass type to functions is using templates:
#include <iostream>
#include <ostream>
#include <typeinfo>
using namespace std;
enum exampleEnum {ONE,TWO,THREE};
template<typename T>
void example()
{
cout << typeid(T).name() << endl;
}
int main()
{
example<exampleEnum>();
return 0;
}
If you structure your enum values properly, you can combine values with the | bit-wise or operator.
enum exampleEnum {One=0x01, TWO=0x02, THREE=0x04, FOUR=0x08}; // one bit set in each
example(ONE | TWO | FOUR);
In your function you need to test for each value individually:
if (value & ONE) // ONE was passed
if (value & TWO) // TWO was passed, etc.
The effect I am trying to achieve is to share an enum across multiple classes and subclasses without redefining it in every class/subclass I wish to use it in. I want these values to be passed instead of using some form a global variable.
Hm, you don't have to redefine it. Just place enum definition outside of these classes. And when you want to use enum values in some class, just include header with that enum.
enum exampleEnum {ONE,TWO,THREE};
class Class1
{
void foo()
{
exampleEnum t=TWO; // use enum values here
}
};
class Class2
{
void bar()
{
exampleEnum t=ONE; // and here
}
};
class Class3
{
void some()
{
exampleEnum t=THREE; // and even here
}
};
EDIT:
By doing it this way I would be adding a dependency to my classes which I am try to avoid. It's better to give something to a class then to have the class take something. While I cannot completely escape from dependencies I was hoping I might have been able to.
In that case you may use templates:
enum exampleEnum {ONE,TWO,THREE};
enum exampleEnumOther {RAZ,DVA,TRI};
template<typename Enum>
class Class1
{
Enum member;
public:
void foo(Enum p)
{
member=p;
}
template<typename OtherEnum>
void bar(OtherEnum val)
{
OtherEnum use=val;
}
};
int main()
{
Class1<exampleEnum> t;
t.foo(ONE);
t.bar(TWO);
t.bar(RAZ);
}
Class1 do not depend on any particular enum.
If your enumeration is contiguous (or, if you never use = in the definition of your enum), there is an easy to do trick is to iterate over the enum.
Start with this:
enum /*class*/ Bob // class optional
{
BeginBob,
ONE = BeginBob, // the first entry needs an = Begin clause.
TWO,
THREE,
EndBob
};
now, you can pass in a range of enum values in a similar way you'd pass an iterator range.
void doWork( Bob b );
void doWork( Bob begin, Bob end )
{
for (Bob i = begin; i != end; i=ststic_cast<Bob>(i+1) )
doWork( i );
}
the begin and end enum values describe a half-open range, like iterators would. So you can call doWork on the entire enum range like this:
void doWork( BeginBob, EndBob );
or, you could call it on everything up to, but not including, THREE like this:
void doWork( BeginBob, THREE );
which calls doWork on ONE and TWO.
You can make template <typename T> example and specialize it on several different enums, allowing you to call example(ONE) to call code specific to exampleEnum and then (given, say enum otherEnum { EINS, ZWEI, DREI } you can call example(EINS) to get code specific to otherEnum.

Map one enum to another enum

There is an existing enum
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides;
I want to create another enum new_myEnumSides and it's values should be mapped to the values of myEnumSides. Hence forth I would be using new_myEnumSides instead of myEnumSides.
Is the code below ok for this purpose?
typedef enum
{
new_myEnum_front = myEnumSides::myEnum_front,
new_myEnum_back = myEnumSides::myEnum_back
} new_myEnumSides;
Or is there a better way?
I can't possibly imagine why do you need to do it... If you don't need to rename the enum's values, you can just make another variable of the first one, without adding another enum (I believe this is not your case, but still have to point out this opportunity):
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides, new_myEnumSides;//<-- just add the new variable here
If you do want to rename it (which I believe, is your case), you should not use the :: operator, but simply write:
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides;
typedef enum
{
new_myEnum_front = myEnum_front,
new_myEnum_back = myEnum_back
} new_myEnumSides;
The :: operator should be used only if the enum is inside a class, structure or namespace, otherwise no :: is needed.
The only reason I can imagine you wanting to do this is to extend an existing enum and create a new one with extra values.
As enum does not offer any form of inheritance, being compile time constants and really just integers, you could do something like this, although I don't particularly recommend it..
// internalEnums.h
myEnum_front = 11,
myEnum_back = 19
// customerEnums.h
someNewValue = 20,
someOtherNewValue = 21
// Wherever you want to define your enums
typedef enum
{
#include "customerEnums.h"
} customerAccessible;
typedef enum
{
#include "internalEnums.h"
#include "customerEnums.h"
} internalUseOnly;
// Now there are two enumerations, sharing items.
customerAccessible::someNewValue // 11
customerAccessible::myEnum_front; // Doesn't exist
EDIT As per your comment, you could expose enumerations to the customer by keeping values in a header specifically for external use.
It's usually the case that you don't want to expose details of third party libraries, but an enumeration that lies there might have the exact members you need.
In that case it's beneficial to create a mapping for the third party enum, so that even if the backend library changes, you can simply provide the enumerators yourself.
The most concise way to do this, is by creating an alias:
using MyEnum = ThirdPartyEnum;
// {
// enumerator1,
// enumerator2
// }
This way, user code won't rely on third party internals,
you avoid doing conversions and even if the third party library is replaced, your users can keep using MyEnum by simply uncommenting the enumerator values (I like to keep them in comments, so users won't have to refer to third party libraries for documentation.