Enum in structure - c++

My question is not really hard but I can't find a proper answer on the web to my problem.
I define a .h file that contains a struct and declare some enum in it. I want to use that struct in another .cpp file. But the compilation return me error.
Here's my code variableStruct.h file :
struct variableSupervision {
std::string Donnees;
enum TYPE
{
ENUM,
INT,
FLOAT,
BOOL
};
enum UNITE
{
ETAT,
A,
V,
TBC,
DEGREEE
};
enum IN
{
SYSTEMMONITOR,
MODEMANAGEMENT
};
enum OUT
{
SLIDECONTROL,
MODEMANAGEMENT,
HMICONTROL,
MOTORCONTROL
};
enum GET {X};
std::string Commentaire ;
};
The error is : redeclaration Of MODEMANAGEMENT. I don't understand why, because they are in two different enum. Should I create different separate file for each enum ?

Since C++11 you can use enum class instead of enum to solve this problem.
If you can't use C++11 for some reason you should prefix your values like this:
enum IN
{
IN_SYSTEMMONITOR,
IN_MODEMANAGEMENT
};
enum OUT
{
OUT_SLIDECONTROL,
OUT_MODEMANAGEMENT,
OUT_HMICONTROL,
OUT_MOTORCONTROL
};
or they can't be placed at the same structure, so you have to move the declarations to different namespaces. (EDIT: or different class / structure as it said below.)

Related

Templated typedef structs with constructor in C++

I have this code right now, which seems to work so far but I was wondering if there was a way to get the exact same struct in a more elegant way since my method so far needs a duplicate everytime for each struct... The end goal would be to have a typedefed struct which would swap the bytes according to the endianness automatically.
using ResourceHeader_t = struct ResourceHeader_s
{
uint32_t magic;
uint32_t chunkVersion;
uint32_t chunkSize;
};
template<bool bigEndian>
struct ResourceHeader : public ResourceHeader_s
{
ResourceHeader(ResourceHeader_t* ptr) : ResourceHeader_s(*ptr)
{
if (bigEndian)
{
LITTLE_BIG_SWAP(magic);
LITTLE_BIG_SWAP(chunkVersion);
LITTLE_BIG_SWAP(chunkSize);
}
}
};
Usage example :
ResourceHeader<true> resourceHeader((ResourceHeader_t *)fileBuffer);
There is no need for a typedef struct declaration in C++. This is a relic of C.
In C++, after declaring a struct ResourceHeader_s, or struct ResourceHeader_t, or just a plain struct ResourceHeader, the same symbol can be used directly by itself, without an explicit struct.
You might simply add the endianess as a ResourceHeader ctor parameter, rather than a template parameter. This would remove duplicate definitions of the struct (one for big and one not).

Passing any enum of a given type as function parameter

I'm working on a project for an AVR microcontroller using the Arduino framework.
I'm building a simple error tracking system structured as a class (ErrorManager). I have defined a couple of functions like
void ErrorManager::error(??? errorCode) { // more on ??? later
// rise error in some way
}
I want to define error codes separately in different modules that make up this project. In each module, I would like to define an enum class containing the codes for that module, and then pass them to the error function above:
namespace someNamespace /* or class SomeClass */ {
// cointains error codes for this class/module/part of the code
enum class ErrorCodes : unsigned int {
none = 0,
anError,
someOtherError
}
void foo() {
error(ErrorCodes::anError);
}
}
(let errManager be the ErrorManager object declared in one module of my project)
I could accomplish this by writing unsigned int in ??? and using an enum instead of an enum class, but that would mean that the error code names would be in scope in the whole module namespace or, at least, in the whole class where they are defined, and I would rather avoid this.
Is there a way to do this with an enum class? For example, something to write in ??? which means "Take any Enum (with unsigned int, or some a typedefined type, or even any integer type) as parameter"?
It seems you need a template:
template <typename T>
void /*ErrorManager::*/error(T x)
{
unsigned int errorcode = (unsigned int)x;
// Do something with it
}
enum class ErrorCodes : unsigned int {
none = 0,
anError,
someOtherError
};
void foo() {
error<ErrorCodes>(ErrorCodes::anError);
}
It should be possible to restrict the template to be an enum using enable_if and is_enum, but I can't get it compiled at the moment. It seems there are standard libraries missing for Arduino.
Please note that the default underlying type of an enum is int, not unsigned int.

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

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.

Extending enums in C++?

Is there a way in C++ to extend/"inherit" enums?
I.E:
enum Enum {A,B,C};
enum EnumEx : public Enum {D,E,F};
or at least define a conversion between them?
No, there is not.
enum are really the poor thing in C++, and that's unfortunate of course.
Even the class enum introduced in C++0x does not address this extensibility issue (though they do some things for type safety at least).
The only advantage of enum is that they do not exist: they offer some type safety while not imposing any runtime overhead as they are substituted by the compiler directly.
If you want such a beast, you'll have to work yourself:
create a class MyEnum, that contains an int (basically)
create named constructors for each of the interesting values
you may now extend your class (adding named constructors) at will...
That's a workaround though, I have never found a satistifying way of dealing with an enumeration...
I've solved in this way:
typedef enum
{
#include "NetProtocols.def"
} eNetProtocols, eNP;
Of course, if you add a new net protocol in the NetProtocols.def file, you have to recompile, but at least it's expandable.
"NetProtocols.def" will contain only the field names:
HTTP,
HTTPS,
FTP
I had this problem in some projects that ran on small hardware devices I design. There is a common project that holds a number of services. Some of these services use enums as parameters to get additional type checking and safety. I needed to be able to extend these enums in the projects that use these services.
As other people have mentioned c++ doesn't allow you to extend enums. You can however emulate enums using a namespace and a template that has all the benefits of enum class.
enum class has the following benefits:
Converts to a known integer type.
Is a value type
Is constexpr by default and takes up no valuable RAM on small processors
Is scoped and accessible by enum::value
Works in case statements
Provides type safety when used as a parameter and needs to be explicitly cast
Now if you define a class as an enum you can't create constexpr instances of the enum in the class declaration, because the class is not yet complete and it leads to a compile error. Also even if this worked you could not extend the value set of enums easily later in another file/sub project .
Now namespaces have no such problem but they don't provide type safety.
The answer is to first create a templated base class which allows enums of different base sizes so we don't waste what we don't use.
template <typename TYPE>
class EnumClass {
private:
TYPE value_;
public:
explicit constexpr EnumClass(TYPE value) :
value_(value){
}
constexpr EnumClass() = default;
~EnumClass() = default;
constexpr explicit EnumClass(const EnumClass &) = default;
constexpr EnumClass &operator=(const EnumClass &) = default;
constexpr operator TYPE() const {return value_;}
constexpr TYPE value() const {return value_;}
};
Then for each enum class we want to extend and emulate we create a namespace and a Type like this:
namespace EnumName {
class Type :public Enum<uint8_t> {
public:
explicit constexpr Type(uint8_t value): Enum<uint8_t>(value){}
constexpr Enum() = default;
}
constexpr auto Value1 = Type(1);
constexpr auto Value2 = Type(2);
constexpr auto Value3 = Type(3);
}
Then later in your code if you have included the original EnumName you can do this:
namespace EnumName {
constexpr auto Value4 = Type(4U);
constexpr auto Value5 = Type(5U);
constexpr auto Value6 = Type(6U);
constexpr std::array<Type, 6U> Set = {Value1, Value2, Value3, Value4, Value5, Value6};
}
now you can use the Enum like this:
#include <iostream>
void fn(EnumName::Type val){
if( val != EnumName::Value1 ){
std::cout << val;
}
}
int main(){
for( auto e :EnumName::Set){
switch(e){
case EnumName::Value1:
std::cout << "a";
break;
case EnumName::Value4:
std::cout << "b";
break;
default:
fn(e);
}
}
}
So we have a case statement, enum comparisons, parameter type safety and its all extensible. Note the set is constexpr and wont end up using valuable RAM on a small micro (placement verified on Godbolt.org. :-). As a bonus we have the ability to iterate over a set of enum values.
If you were able to create a subclass of an enum it'd have to work the other way around.
The set of instances in a sub-class is a subset of the instances in the super-class. Think about the standard "Shape" example. The Shape class represents the set of all Shapes. The Circle class, its subclass, represents the subset of Shapes that are Circles.
So to be consistent, a subclass of an enum would have to contain a subset of the elements in the enum it inherits from.
(And no, C++ doesn't support this.)
A simple, but useful workaround for this c++ gap could be as follows:
#define ENUM_BASE_VALS A,B,C
enum Enum {ENUM_BASE_VALS};
enum EnumEx {ENUM_BASE_VALS, D,E,F};
Actually you can extend enums in a round about way.
The C++ standard defines the valid enum values to be all the valid values of the underlying type so the following is valid C++ (11+). Its not Undefined Behaviour, but it is very nasty - you have been warned.
#include <cstdint>
enum Test1:unit8_t {
Value1 =0,
Value2 =1
};
constexpr auto Value3 = static_cast<Test1>(3);
constexpr auto Value4 = static_cast<Test1>(4);
constexpr auto Value5 = static_cast<Test1>(5);
Test1 fn(Test1 val){
switch(val){
case Value1:
case Value2:
case Value3:
case Value4:
return Value1;
case Value5:
return Value5;
}
}
int main(){
return static_cast<uint8_t>(fn(Value5));
}
Note that most of the compilers don't consider the additional values as part of the set for generating warnings about missing enums values in switch statements.So
clang and gcc will warn if Value2 is missing but will do nothing if Value4 is missing in the above switch statement.
One might try this :)
struct EnumType
{
enum
{
None = 0,
Value_1 = 1,
Value_2 = 2,
Value_3 = 3
};
//For when using the EnumType as a variable type
int Value { None };
};
struct EnumTypeEx : EnumType
{
enum
{
ExValue_1 = 3,
ExValue_2 = 4,
//override the value of Value_3
Value_3 = 3000
};
};
Pros:
Class like extensibility
Can override base labels value
Cons:
Tedious to write
You have to explicitly set the value for each label(*)
(*) you can start the auto value increment from the last base value by just writing it explicitly eg. ExValue_Start = LastBaseValue.
I do this
enum OPC_t // frame Operation Codes
{
OPC_CVSND = 0 // Send CV value
, OPC_CVREQ = 1 // Request CV (only valid for master app)
, OPC_COMND = 2 // Command
, OPC_HRTBT = 3 // Heart Beat
};
enum rxStatus_t // this extends OPC_t
{
RX_CVSND = OPC_CVSND // Send CV value
, RX_CVREQ = OPC_CVREQ // Request CV
, RX_COMND = OPC_COMND // Command
, RX_HRTBT = OPC_HRTBT // Heart Beat
, RX_NONE // No new Rx
, RX_NEWCHIP // new chip detected
};
http://www.codeproject.com/KB/cpp/InheritEnum.aspx goes over a method to created an expanded enum.
Create InheritEnum.h:
// -- InheritEnum.h
template <typename EnumT, typename BaseEnumT>
class InheritEnum
{
public:
InheritEnum() {}
InheritEnum(EnumT e)
: enum_(e)
{}
InheritEnum(BaseEnumT e)
: baseEnum_(e)
{}
explicit InheritEnum( int val )
: enum_(static_cast<EnumT>(val))
{}
operator EnumT() const { return enum_; }
private:
// Note - the value is declared as a union mainly for as a debugging aid. If
// the union is undesired and you have other methods of debugging, change it
// to either of EnumT and do a cast for the constructor that accepts BaseEnumT.
union
{
EnumT enum_;
BaseEnumT baseEnum_;
};
};
And then to use:
enum Fruit { Orange, Mango, Banana };
enum NewFruits { Apple, Pear };
typedef InheritEnum< NewFruit, Fruit > MyFruit;
void consume(MyFruit myfruit);
YMMV.
Just an idea:
You could try to create an empty class for each constant (maybe put them all in the same file to reduce clutter), create one instance of each class and use the pointers to these instances as the "constants". That way, the compiler will understand inheritance and will perform any ChildPointer-to-ParentPointer conversion necessary when using function calls, AND you still get type-safety checks by the compiler to ensure no one passes an invalid int value to functions (which would have to be used if you use the LAST value method to "extend" the enum).
Haven't fully thought this through though so any comments on this approach are welcome.
And I'll try to post an example of what I mean as soon as I have some time.
My approach slightly differs from that chosen by Marco.
I have added a macro as the last value of the enum I want to extend. In a separate header, I have defined that macro with the enum entries I want to add.
// error.h
#ifndef __APP_DEFINED__
#define __APP_DEFINED__
#endif
typedef enum { a, b, c, __APP_DEFINED__ } Error;
To add more values, I have created
// app_error.h
#define __APP_DEFINED__ d, e, f,
Lastly, I have added -include app_error.h to the compiler flags.
I prefer this approach compared to placing an #include "app_error.h" directive within the enum, mainly because I need the freedom not to have the "app_error.h" file at all in some projects.
The following code works well.
enum Enum {A,B,C};
enum EnumEx {D=C+1,E,F};