I have some C++ code, in which the following enum is declared:
enum Some
{
Some_Alpha = 0,
Some_Beta,
Some_Gamma,
Some_Total
};
int array[Some_Total];
The values of Alpha, Beta and Gamma are sequential, and I gladly use the following cycle to iterate through them:
for ( int someNo = (int)Some_Alpha; someNo < (int)Some_Total; ++someNo ) {}
This cycle is ok, until I decide to change the order of the declarations in the enum, say, making Beta the first value and Alpha - the second one. That invalidates the cycle header, because now I have to iterate from Beta to Total.
So, what are the best practices of iterating through enum? I want to iterate through all the values without changing the cycle headers every time. I can think of one solution:
enum Some
{
Some_Start = -1,
Some_Alpha,
...
Some_Total
};
int array[Some_Total];
and iterate from (Start + 1) to Total, but it seems ugly and I have never seen someone doing it in the code. Is there any well-known paradigm for iterating through the enum, or I just have to fix the order of the enum values? (let's pretend, I really have some awesome reasons for changing the order of the enum values)...
You can define an operator++() for your enum. This has the advantage that it uses the well-known paradigm of the standard incrementation operators. :)
Depending on whether your enums are contiguous, you can treat them as int or use a switch:
Some& operator++(Some& obj)
{
# if YOUR_ENUMS_ARE_CONTIGUOUS
int i = obj;
if( ++i > Some_Total ) i = Some_Alpha;
return obj = static_cast<Some>(i);
# else
switch(obj)
{
case Some_Alpha : obj = Some_Beta; break;
case Some_Beta : obj = Some_Gamma; break;
case Some_Gamma : obj = Some_Total; break;
case Some_Total : obj = Some_Alpha; break;
default: assert(false); // changed enum but forgot to change operator
}
return obj;
# endif
}
Note that, if operator++() is defined, users will probably expect an operator--(), too.
No, there is no way of doing this because there is no guarantee that someone hasn't written code like:
enum Some
{
Some_Alpha = 0,
Some_Beta,
Some_Gamma = 42,
Some_Delta,
Some_Total
};
You can check out this article with its source code on how you can implement this with static class members.
In C++11 (and probably earlier), you could use the following hack, to make Some iterable:
Some operator++(Some& s) {
return s = (Some )(std::underlying_type<Some>::type(x) + 1);
}
Some operator*(Some s) {
return s;
}
Some begin(Some s) {
return Some_Alpha;
Some end(Some s) {
return Some_Gamma;
}
int main() {
// the parenthesis here instantiate the enum
for(const auto& s : Some()) {
// etc. etc.
}
return 0;
}
(This answer was shamelessly adapted from here.)
enum Some
{
Some_first_ = 0,
Some_Alpha = Some_first_,
....
Some_last_
};
Doing such you can grant first & last never changes order
If you do not use any assignments, the enums are guaranteed to be sequential starting with 0 as the first.
thers.
The best thing you can do is keep them in the order you want in your enum definition, and cycle through them with the for loop.
I place all Enums in their own namespace. Example:
namespace Foo {
enum Enum {
First=0, // must be sequential
Second,
Third,
End // must be last
};
}
In code:
for (int i=Foo::First; i!=Foo::End; i++) {
// do stuff
}
This is because C++ allows stuff like this (not tested in a compiler):
enum Foo {
Alpha = 1
};
enum Bar {
Beta = 2
};
Foo foo = Beta;
Which is clearly wrong.
Related
Is there some sort of compile-time switch statement that I can use to pass parameters to a constructor for a member variable? Right now, I have a controller (in the control systems sense, not the MVC sense) that I need to be able to configure its operating frequency at compile time and a filter whose parameters depend on the selected frequency. Here is a skeleton of how I've implemented it:
#include <cstdint>
class Filter {
public:
Filter(float p1, float p2) : p1(p1), p2{p2} {}
private:
float const p1;
float const p2;
};
class Controller {
public:
Controller(void) {}
private:
static constexpr uint32_t frequency = 200U;
Filter filter{frequency == 400U ? 3.0f : // p1
frequency == 200U ? 1.0f :
frequency == 50U ? 0.55f : 0f,
frequency == 400U ? 2.0f : // p2
frequency == 200U ? 9.0f :
frequency == 50U ? 37.1f : 0f,
};
static_assert(frequency == 400U || frequency == 200U || frequency == 50U, "Invalid frequency");
};
This is obviously very difficult to maintain for large numbers of frequencies, even for only two filter parameters (the real software has more). Every time I need to add support for a new frequency, I need to add code to n points in the code, where n is the number of parameters for the filter. What I would like is something like this:
Filter filter = frequency == 400U ? {3.0f, 2.0f} :
frequency == 200U ? {1.0f, 9.0f} :
frequency == 50U ? {0.55f, 37.1f} :
{0.0f, 0.0f};
Or, in my wilder dreams:
Filter filter = static_switch_map(frequency) {
400U: {3.0f, 2.0f},
200U: {1.0f, 9.0f},
50U: {0.55f, 37.1f},
};
The parameters for the filter are not formulaically determined and thus cannot be written as part of an expression. Some additional notes:
I am using c++14 extensions in clang and GNU C++.
I am open to using a higher c++ extension and compiler extensions specific to GNU C++, though c++14 in both clang and GNU C++ preferred. clang-only solutions are no good to me.
This is for use in an embedded environment; a run-time solution using switch plus new plus pointers is unacceptable because of the indirection performance hit, binary file bloat, and the un-safeness of memory allocation in the embedded environment.
The Filter class may be instantiated multiple times.
Solutions involving templates are okay; I'm only using floats right now because I'm porting someone's Matlab code, but I will eventually switch to fixed-point math.
Other solutions I have considered include:
Conditional compilation using macros and define (the frequency variable I'm using in the real code is a custom data type, so I'd need to use define and a C++ variable that have similar roles; I don't like the idea of having frequency defined in two locations -- that's going to lead to maintenance problems down the road).
Rewriting variables using a custom preprocessor during the build process. Too magical and will likely become a gotcha to someone in the future.
Enums. I haven't ruled these out, but I can't think of how to use them in a way that would improve the code without the abilities of Java enums and/or a Python-like *args expansion. Admittedly, I've only been writing C++ for about four months (non-consecutively) and only had a solid year of experience with C before that, so there's a good chance I'm missing something, syntax-wise.
Separate include file to contain the magic; in my project, all automatically generated files have a separate extension, so this works. However, I prefer to have simpler build scripts and keep as much of the logic in the C++ code as possible.
Put your switch in a factory method and make your constructor private, so that you are forced to use that method.
This way you'll have only one point to update in your code in future:
struct Filter {
static Filter create(int freq) {
switch(freq) {
case 0: return { 0, 1 };
case 2: return { 3, 7 };
default: return { 0, 0 };
}
}
private:
Filter(int, int) {}
};
int main() {
auto filter = Filter::create(2);
(void)filter;
}
If you want to use it also at compile-time, you can slightly change it as it follows (this requires C++14):
class Filter {
constexpr Filter(int i, int j)
: i{i}, j{j}
{}
public:
static constexpr Filter create(int freq) {
switch(freq) {
case 0: return { 0, 1 };
case 2: return { 3, 7 };
default: return { 0, 0 };
}
}
constexpr int get_i() const { return i; }
constexpr int get_j() const { return j; }
private:
int i;
int j;
};
int main() {
constexpr auto filter = Filter::create(2);
static_assert(filter.get_i() == 3, "!");
}
Of course, you can easily add a copy constructor or whatever to your Filter class. This is a minimal example to show how the pattern works, nothing more.
Another way to define them separately and use each constructor through a call to a factory method is based on delegating constructors:
template<int>
struct freq_tag {};
class Filter {
constexpr Filter(int i, int j)
: i{i}, j{j}
{}
constexpr Filter(freq_tag<0>): Filter{0, 1} {}
constexpr Filter(freq_tag<2>): Filter{3, 7} {}
template<int N>
constexpr Filter(freq_tag<N>): Filter{0, 0} {}
public:
template<int N>
constexpr static Filter create() {
return Filter{freq_tag<N>{}};
}
constexpr int get_i() const { return i; }
constexpr int get_j() const { return j; }
private:
int i;
int j;
};
int main() {
constexpr auto filter = Filter::create<2>();
static_assert(filter.get_i() == 3, "!");
}
It's mainly a matter of taste if compared to the switch-based solution, but for the fact that this one should work also in C++11.
This is certainly related to a bunch of other questions which have been answered, but I have been unable to derive the answer for my specific case from them, largely because I'm not actually a programmer; I'm just an engineer who happens to have to write some code.
Here's the situation:
I have a bunch of variables I'd like to collect together, probably into a structure.
All but two I would like to initialize to zero; two specific variables (which don't happen to be the first two) need to be initialized to one.
The actual names are unique and meaningful enough that using a vector wouldn't be appropriate, plus there are some doubles in there too. I'm keeping my example below simple for clarity.
Because of the project I'm working on, I'm stuck with C++98, so even if C++11 has more elegant solutions, they won't work for me.
I am thinking something along these lines for the structure itself:
struct allFlags
{
int flagAA;
int flagAB;
int flagAC;
int flagAD;
int flagAE;
// ...
// there's about 100 variables total
// ...
int flagZZ;
};
I want to have all the flags initialized to 0 except for flagAD and flagAE, which should be 1.
So first of all, I am not sure if I should use typedef struct allFlags or struct allFlags. Next, I am not sure if I should be creating a constructor (which I think only would apply in the case of no typedef?) or making the defaults happens when I instantiate the structure. I have seen things like this (which would be put inside the struct definition):
allFlags() : flagAD(1), flagAE(1) { /*not sure of I'd need anything here*/ }
but I wouldn't want to have to list out all other ~98 variables by name individually in the constructor body to set them to zero. I have also seen things using memset which could potentially help, but I'm not sure the best way to do it.
And finally one additional related question is how to actually declare an instance of my structure (which results in the initial values I want). It looks like sometimes a struct is instantiated with the new keyword and sometimes is it treated more like a base data type, i.e. I have seen both of these in searching:
allFlags flagset1;
flagset2 = new allFlags;
I have also seen syntax which would be like this rather than using a constructor at all:
allFlags flagset3 = {}; // to zero all fields first
flagset3.flagAD = 1;
flagset3.flagAE = 1;
but I'd rather keep the instantiation as clean and simple as possible.
Please forgive the question. I have tried to do my homework before asking, but my C++ knowledge is mediocre at best and so some of the seemingly relevant answers I've found I either didn't fully understand or just raised more questions.
If you feel comfortable with using templates, you can use a class template to automate clean initialization of all member variables of allFlags.
// class template to help initialize members cleanly.
template <typename T>
struct flag
{
// Constructors
flag() : val(0) {}
flag(T const& v) : val(v) {}
// Automatic cast operators to T
operator T& () { return val; }
operator T const& () const { return val; }
// Comparison operators
bool operator==(flag const& rhs) const { return val == rhs.val; }
bool operator!=(flag const& rhs) const { return val != rhs.val; }
bool operator<(flag const& rhs) const { return val < rhs.val; }
T val;
};
typedef flag<int> IntFlag;
typedef flag<double> DoubleFlag;
struct allFlags
{
// Initialize all flags bug flagAD to zero.
allFlags() : flagAD(1) {}
IntFlag flagAA;
IntFlag flagAB;
IntFlag flagAC;
IntFlag flagAD;
IntFlag flagAE;
IntFlag flagZZ;
};
#include <iostream>
int main()
{
allFlags f;
std::cout << f.flagAA << " " << f.flagAD << std::endl;
}
Output:
0 1
You answered your own question quite well:
allFlags flagset3 = {}; // to zero all fields first
flagset3.flagAD = 1;
flagset3.flagAE = 1;
It is clean, and very clear about your intentions. Later, when someone else has to read your code they will understand exactly what you are trying to do.
It is similar to what you see in device driver programming:
registerX = 0 | 1 << BIT2 | 1 << BIT3;
I have a structure that contains x amount of integers, It is required that every last one of them be non-zero. Here's my structure:
struct thingy_t{
int a, b, c /* and so on */;
bool init();
};
Over time I will be adding many other members to the structure, which makes it an issue if I forget to check if it's non-zero. That's why I wanted to automate it for every member.
In my init function, it attempts to get values for the members, and return false if any of them are 0.
So far I have this:
bool thingy_t::init(){
a = GetValue(/* blah blah */); // Will return 0 if it can't find anything
b = GetValue(/* other blah */);
/* and so on */
// Check if any value is zero
for(int* i = (int*)this
; i < (int*)((char*)this + sizeof(interfaces_t))
; i++){
if(!*i) return false;
}
return true;
}
I am looking for a better way of doing this that would be more readable and more memory safe, as I am playing with fire(pointers) in a way they probably aren't intended.
Also, sorry for the for loop, I tried to make it more readable by wrapping it, but I probably made it worse.
There isn't a natural way to iterate over the struct and check for certain values of the members you have, so the better option for you, in my opinion, should be either make a better design for your task or make sure that you check for incorrect values on each access to that struct.
I'd simple implement the type to contain an array of int or (possibly better) a standard container.
If the number of values is specified at compile time ....
struct thingy_t
{
int x[number];
bool all_non_zero() const;
};
bool thingy_t::all_non_zero() const
{
for (int i = 0; i < number; ++i)
if (!number[i]) return false;
return true;
}
If the number is not specified at compile time, I'd use a standard container
struct thingy_t
{
std::vector<int> x;
thingy_t(std::size_t size) : x(size) {};
bool all_non_zero() const;
};
bool thingy_t::all_non_zero() const
{
for (std::vector<int>::const_iterator it = x.begin(), end = x.end();
it != end number; ++it)
if (!(*it)) return false;
return true;
}
The above works for all versions of C++, but may be simplified in C++11 or later.
bool thingy_t::all_non_zero() const
{
for (const auto &element : x)
if (!element) return false;
return true;
}
Naturally, you will need other functions to actually store values in the array or vector.
The code won't change if the number of integers changes. You will need to somehow track separately the meaning of each element.
I solved my own question while enjoying a nice breakfast.
Here's how I solved it:
struct thingy_t{
union{
struct{
int a, b, c;
}
int arr[3];
}
}
That way I can access variables via. their name and also their index in an array so I can check if each value is non-zero easier (creds: James Root for the array inspiration)
I have a C++ class containing a bunch of data members of the same type and I want to iterate over them:
// C.h
class C {
// other members
double foo;
double bar;
...
double barf; // 57th double declared since foo, nothing else in between
// other members
};
Pointer arithmetic seems to work, e.g. here using the constructor to initialize those 58 member doubles:
// C.cpp
C::C() {
for (int i = 0; i < 58; i++) {
*(&this->foo + i) = 0;
}
}
I found related questions here How to iterate through variable members of a class C++, here C++: Iterating through all of an object's members?, here Are class members garaunteed to be contiguous in memory? and here Class contiguous data, with some people suggesting this kind of thing is ok and others a no-no. The latter say there's no guarantee it won't fail, but don't cite any instances of it actually failing. So my question is, does anyone else use this, or has tried and got into trouble?
Or maybe there's a better way? Originally in my application I did actually use an array instead to represent my object, with indices like so:
int i_foo = 0, i_bar = 1, ..., i_barf = 57;
However once I introduced different objects (and arrays thereof) the index naming started to get out of hand. Plus I wanted to learn about classes and I'm hoping some of the other functionality will prove useful down the line ;-)
I use the iteration pretty heavily, e.g. to calculate statistics for collections of objects. Of course I could create a function to map the class members to an array one-by-one, but performance is a priority. I'm developing this application for myself to use on Windows with VS. I would like to keep other platform options open, but it's not something I intend to distribute widely. Thanks
George:
I think you can have a better solution (like a method that will return the i-th attribute:
double get(size_t idx)
{
switch (idx)
{
case 0: return foo;
case 1: return bar;
case 2: return foo_bar;
....
}
}
Using pointer arithmetic to iterate over class data members can cause problems during code optimization. Example:
struct Vec3
{
double x, y, z;
inline Vec3& operator =(const Vec3& that)
{
x = that.x;
y = that.y;
z = that.z;
return *this;
}
inline double& operator [](int index)
{
return (&x)[index];
}
};
...
Vec3 foo = bar; // operator =
double result = foo[2]; // operator []
...
Both operators are inlined, the value of the result depends on the final instructions reordering. Possible cases:
foo.x = bar.x;
foo.y = bar.y;
foo.z = bar.z;
result = (&foo.x)[2]; // correct -- result contains new value
foo.x = bar.x;
foo.y = bar.y;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.z = bar.z;
foo.x = bar.x;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.y = bar.y;
foo.z = bar.z;
Some compilers just do not realise that (&foo.x)[2] is the same data as foo.z and they reorder instructions incorrectly. It is very hard to find bugs like this.
I have the following enum and map:
typedef enum {
MaxX = 0,
MaxY,
MaxCells,
MaxCycles,
Threes
} SettingName;
typedef std::map<SettingName, const char*> SettingNameCollection;
SettingNameCollection settingNames;
And I have the following function to return the enum name:
const char* gofBoard::getSettingName(unsigned x) {
return settingNames[static_cast<SettingName>(x)];
}
And from what I've read that should work, but the function doesn't return anything. There's no compile time errors, and no runtime errors.
Here's my suggestion:
1- Write this macro:
#define SMART_STRINGIFY_CASE(ENUM_CODE) case ENUM_CODE: return # ENUM_CODE
2- Write this function:
const char* SettingNamesToString( settingNames const input)
{
switch(input)
{
SMART_STRINGIFY_CASE(MaxX);
SMART_STRINGIFY_CASE(MaxY);
...
default:
// your own !
}
The operator[] is used to retreive/insert data in a std::map. You might be more conformtable with std::map::find:
const char* gofBoard::getSettingName(unsigned x) {
auto found = settingNames.find(static_cast<SettingName>(x));
if (found == settingNames.end())
/* throw appropriate exception */
/* or assert */
assert ( found != settingNames.end() );
return found->second;
}
EDIT: like someone said, for your purpose, a simple std::array would be enough.
If you do not populate the map before you call that function, what you are getting isnt an error, its a blank string (im guessing)
You want to do something like this
typedef std::array<const char*,Threes+1> SettingNameCollection;
// usually for such purposes, sometimes an extra enum is added to give you number of valid enum values ( Settings_Num for instance)
SettingNameCollection settingNames {
"MaxX ",
.....
"Threes",
}; // first time using the new syntax, is this correct?
const char* gofBoard::getSettingName(SettingName setting) {
return settingNames[setting]; //do i need to cast to int in c++11?
}
A map is certainly overkill if your enum is contiguous. I would suggest switching to a macro definition.
Excerpt:
SANDBOX_DEFINE_ENUM(MyEnum, (Foo)(Bar)(Team))
Will expand to:
struct MyEnum {
enum Type {
Foo,
Bar,
Team
};
static Type const First = Foo;
static Type const Last = Team;
};
inline char const* toString(MyEnum::Type value) {
switch(value) {
case MyEnum::Foo: return "Foo";
case MyEnum::Bar: return "Bar";
case MyEnum::Team: return "Team";
}
return 0;
}
Everyone who programmed in C++ extensively has run into the problem of enum to string conversion (and string to enum conversion). There are various aspects to consider to solve the problem well, e.g. what if the string for an invalid enum is requested. I think you will benefit by using a generic solution that you can use for most or all of your enums. That problem is covered by this question:
Which Typesafe Enum in C++ Are You Using?