The following class is given:
class Button {
public:
enum Color{RED, GREEN, BLUE};
Color color = RED;
void setToBlue() {
Color* colorPtr = &color;
*colorPtr = BLUE;
//colorPtr->BLUE;
}
}
If I call setToBlue(), will BLUE not be destroyed until Button is destroyed? Why is the out commented instruction not valid?
Your code is perfectly valid.
*colorPtr = BLUE;
copies the value of BLUE into the pointed to object. Which in this case is color, which is a member of Button and thus is guaranteed to exist until the Button object is destroyed.
Note that
void setToBlue() {
color = BLUE;
}
Is exactly the same in this case.
To answer your edit:
Why is the out commented instruction not valid?
Because what operator -> does is the same as (*colorPtr).. The . operator is the member access operator, an enum doesn't have any members to access and thus it makes no sense.
I think there's a fundamental confusion here about what an enum is. Probably the best way to see them for this sample is as a #define.
Imagine that instead you had
#define BLUE 2
and then did colour = BLUE; this would breakdown to colour = 2
Since '2' is now hard coded in the memory of the binary, it's scope is global.
Related
UPDATE: I just did some benchmarking of the core conversion logic for various solutions. Here are the CPU times in nanoseconds for a single iteration, averaged out of five million iterations on Wandbox:
8 - switch statement
176 - static map
3800 - dynamic map
As you can see, creating a new map every time (dynamic mapping) is relatively time consuming. Creating the map once (static mapping) and just referring to it thereafter is almost 22 times faster. But, coincidentally, the original switch-based solution is 22 times faster than static mapping!
Hmm... I never considered dynamic mapping a viable solution but had hopes for static mapping. It's quite a bit slower than the good, old switch statement, but does 8 nanoseconds versus 176 nanoseconds really matter?
End of update
The core problem I'm trying to solve is translating from one "namespace" to another (in the general sense, not re the C++ namespace keyword). This is common in programming, usually solved in C++ with a switch statement like this:
#include <iostream>
enum MUSIC { ROCK, RAP, EDM, COUNTRY };
enum COLOR { RED, BLUE, ORANGE, WHITE };
COLOR convert(MUSIC music)
{
COLOR color = WHITE;
switch (music) {
case RAP: color = RED; break;
case EDM: color = BLUE; break;
case ROCK: color = RED; break;
}
return color;
}
int main()
{
COLOR c = convert(COUNTRY);
std::cout << c << std::endl;
}
The following is my solution (the templates will be tucked away in a header file somewhere). The convert() function works with any types that are valid for std::map, e.g., enum to enum and long to std::string. The first parameter is the key, or "from" value, the second is the default value if can't be converted, and the return value is the mapped, or "to," value. (Special thanks to #Yakk for help with template argument deduction.)
#include <iostream>
#include <map>
#include "boost/assign.hpp"
template<class T> struct no_deduction { typedef T type; };
template<typename Key, typename T>
T convert(const Key &k, const T &d, const typename no_deduction<std::map<Key, T> >::type &m) {
typename std::map<Key, T>::const_iterator it = m.find(k);
return it == m.end() ? d : it->second;
}
using boost::assign::map_list_of;
enum MUSIC { ROCK, RAP, EDM, COUNTRY };
enum COLOR { RED, BLUE, ORANGE, WHITE };
int main()
{
COLOR c = convert(COUNTRY, WHITE, map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED));
std::cout << c << std::endl;
}
Anyway, notice that map_list_of, above, creates the same list every time it's called. I'd like it to be static. This is the obvious solution:
static const std::map<MUSIC, COLOR> m = map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED);
COLOR c = convert(COUNTRY, WHITE, m);
But I'm trying to make it simple to use, in particular, as a single statement. Here's a macro solution, but I'd rather avoid that, too.
#define CONVERT(f,t,d,m) do{static const std::map<BOOST_TYPEOF(f), BOOST_TYPEOF(d)> m_ =\
map_list_of m; t = convert(f, d, m_);}while(0)
COLOR c;
CONVERT(COUNTRY, c, WHITE, (RAP, RED) (EDM, BLUE) (ROCK, RED));
Does anybody know of some C++ magic (C++03, actually) that can call my convert() function
with a static map,
as a single statement, and
without using a macro?
Why not just simply use a static array and index it ?
enum MUSIC { ROCK = 0, RAP = 1, EDM = 2, COUNTRY = 3 };
enum COLOR { RED, BLUE, ORANGE, WHITE };
static const COLOR music_to_color[] =
{
RED, //maps to 'ROCK = 0'
BLUE, //maps to 'RAP = 1'
ORANGE, //maps to 'EDM = 2'
WHITE //maps to 'COUNTRY = 3'
};
MUSIC music = RAP;
std::cout << music_to_color[music] << std::endl;
The body of your convert function can be only return music_to_color[music] (where music would be the argument) in this case.
The advantages of this approach are speed and lack of additional runtime overhead of creating a std::map of something simmilar. Disadvantage would be the fact that you cannot easily modify the map on runtime and it is more "C-like" than "C++ like" (you can ease the pain using std::array instead of static array if you need C++ interface: iterators, etc.)
Another way to do the same thing is to use template specializations, but it is a lot of typing and it would be difficult to maintain if you had a lot of values to map.
Uppercase names are conventionally reserved for macros, so I renamed them.
At some point you are going to have to do the work of coding how one enum type converts to another. The easiest way using a map is as follows:
Color convert(Music music)
{
static const std::map<Music, Color> converter = { { Rap, Red }, { Edm, Blue }, { Rock, Red } };
return converter.at(music);
}
This uses initializer lists which is a C++11 feature. If you can't use that, you can try:
Color convert(Music music)
{
static const struct Once
{
Once()
{
converter[Rap] = Red;
converter[Edm] = Blue;
converter[Rock] = Red;
}
std::map<Music, Color> converter;
} once;
std::map<Music, Color>::const_iterator find_it = once.converter.find(music);
assert(find_it != once.converter.end());
return find_it->second;
}
This code might not use fancy macros but it's safe, reasonably efficient (one instance of the map) and readable (although I did do a trick with that struct there). There are faster ways but they are more complicated and probably not necessary for your use case.
If there are less than a dozen enum values, I would consider just using a switch statement however. It is usually faster than a map.
When using an enum in C++ how does one create getter and setters?
Example:
enum class FieldLayerStates
{
kEmpty = 0, // new to the game.
kActive = 1, // has fields already in the same.
kAdd = 2 // field layer is ready to have a field added.
};
FieldLayerStates _fieldLayerState;
inline FieldLayerStates getFieldLayerState() { return _fieldLayerState; };
inline void setFieldLayerState(FieldLayerStates i) { _fieldLayerState = i; };
I am getting errors at the inline functions:
: Unknown type name 'FieldLayerStates'
: Cannot initialize return object of type 'int' with an lvalue of type 'FieldLayer::FieldLayerStates'
and when I go to use it:
// check the status of the layer to see if it has fields in it already (loaded from CCUserDefaults
if (getFields().empty())
{
// nothing, this must be our first time in.
setFieldLayerStatus(kEmpty);
}
It says kEmpty is undeclared.
Can someone help me clear up my confusion?
You're using an enum class, are you sure that's what you want?
If you stop doing that your code will work.
otherwise refer to FieldLayerStates::kEmpty (because enumerators of an enum class must be qualified by their type name)
I don't know why you get the Unknown type name 'FieldLayerStates' error because you haven't shown enough context to understand the code, at a guess I'd say you're trying to define the functions outside the class and you need to say FieldLayer::FieldLayerStates
Please show the full code so we have a chance of seeing what you're really compiling.
enum class Foo
is a new C++11 language feature that means "strongly typed, and scoped" enumerations. It is significantly different than just
enum Foo
When you use strongly typed enums, you have to qualify them with the scope they are contained in.
enum class Colors { Red, Green, Blue };
enum class Moods { Happy, Bored, Blue };
Without the "class", this won't compile, because you have defined "Blue" twice. With the "Class" you have actually defined two scopes with their own, private, scoped enums, that require the "::" operator to access.
The "class" are also strongly typed, which means that they won't cast - e.g. to an integer type - without you explicitly casting them.
enum COLORS { RED, GREEN, BLUE };
enum class Colors { Red, Green Blue };
int i = RED; // Legal
Colors j = Colors::Red; // Legal
int i = Colors::Red; // Illegal: Colors::Red is not an integer, it's a Colors.
Colors j = Red; // Illegal: You didn't specify the scope.
Colors j = RED; // Illegal: RED is an integer, not a Colors.
for (int i = RED; i <= BLUE; ++i) { cout << i << endl; } // Legal
// But Colors is not a numeric type, you can't do math or increment on it,
// so the following is illegal:
for (auto j = Colors::Red; j <= Colors::Blue; ++j)
enum class Flags = { Herp = 1, Derp = 2 };
Flags combo = Flags::Herp;
combo |= Flags::Derp; // Illegal, no '|' operator for Flags, casting required.
I think you just want this
enum FieldLayerStates
{
kEmpty = 0, // new to the game.
kActive = 1, // has fields already in the same.
kAdd = 2 // field layer is ready to have a field added.
};
I have a class Color that holds values for the red, green, blue, and alpha channels of a color. The class constructor lets you create a new color by specifying values for the four channels. However, for convenience, I would also like to have some "premade" colors available for the programmer. For example instead of having something like
DrawBox(new Color(255, 0, 0));
you would be able to say
DrawRectangle(Color::Red);
Where Color.Red is an instance of Color that lives inside the Color class. How can I declare these instances of Color inside the Color class? I'm sure there's a name for this technique, but I had no idea what search terms to use when I was looking for help online.
I'm not using any built-in or publicly-available classes or libraries because this is part of a personal exercise in creating a basic graphics stack.
Thanks for your help!
First of all, avoid using new. You could use Color as simple value-type.
Now as an answer to your question, yes, you can do that as:
//color.h
typedef unsigned char byte;
class Color
{
public:
//declaration
const static Color Red;
const static Color Green;
const static Color Blue;
public:
Color(byte red, byte green, byte blue);
};
//define the static members in color.cpp file
#include "color.h"
const Color Color::Red(255,0,0);
const Color Color::Green(0,255,0);
const Color Color::Blue(0,0,255);
Then use Color::Red as you want to use.
I have class like following:
class Car
{
public:
Car();
// Some functions and members and <b>enums</b>
enum Color
{
Red,
Blue,
Black
};
Color getColor();
void setColor(Color);
private:
Color myColor;
}
I want to:
access to Color values as Color::Red. It is really hardly to understand code when Car::Red is used, when class have a lot enums, subclasses etc.
use type Color as function argument or return value
use variable type Color in switch
I know 3 partial solutions:
Using embedded class Color and enum in it
Using embedded namespace Color and enum in it
Using enum class
1 and 2 solutions solves a Color::Red accession problem, but I can't use functions like Color getColor() and void setColor(Color).
3 solution has a problem: VS2010 doen't support enum class. GCC v.4.1.2 doesn't support it too. I don't know about later versions of gcc.
Yes, I'm working on cross-platform project.
I have found this solution, but it seems ... heavy.
I hope somebody can help me here :)
In current C++ (i.e. C++11 and beyond), you can already access enum values like that:
enum Color { Red };
Color c = Color::Red;
Color d = Red;
You can go further and enforce the use of this notation:
enum class Color { Red };
Color c = Color::Red;
// Color d = Red; <-- error now
And on a sidenote, you now define the underlying type, which was previously only possible with hacky code (FORCEDWORD or so anyone?):
enum class Color : char { Red };
Name the enum inside the nested class (as example one):
class Car
{
public:
struct Color
{
enum Type
{
Red,
Blue,
Black
};
};
Color::Type getColor();
void setColor(Color::Type);
};
When I want to do something like this I tend to use a namespace and a typedef outside of th namespace (though usually I'm doing this globally rather than inside a class). Something like this:
namespace colors
{
enum Color
{
Red,
Blue
...
}
}
typedef colors::Color Color;
This way you use the namespace to get at the actual colors, but the Color type itself is still globally accessible:
Color myFav = colors::Red;
Hey all, I'm working on cleaning up my code from previous semesters.
Previously I created a 151 color swatch library in c++. However because of my time crunch and lack of experience, I created it entirely as a block of define statements. Which, for hard coding values into spots worked fine. However there are some obvious weaknesses to this approach.
What I have panned out so far, is to create a namespace 'swatch' and inside the namespace I would have an enumeration for the valid colors. I would also have a 'getSwatch' function, or something similar, that would return a vec3 (a class of mine, represents a vector of 3 elemets, with some nice functionality), and the function would use a switch statement to go through the valid swatches.
It would look something like this:
namespace swatch{
enum color{
red,
blue,
green
}
inline
const vec3 getColor(const color& c){
// Switch and return red blue or green.
}
}
My Question: I'd like to know how you might suggest doing this? Benifits of preformance, and usability is what I'm most interested in.
Thanks in advance friends,
Happy coding.
Edit: I just changed the example to make more sense to people who don't know how I use my vec class. (i.e: Everybody but me). Also, you can just look at the other anwsers for usage. They made a good guess on passing rgb values to the constructor, thats not how I did it, but I can still follow along just fine with what you mean.
Use a lookup table:
/************* .h *************/
enum color{
red,
blue,
green,
colors_count
}
const vec3 &getColor(color c)
{
extern const vec3 colors_table[colors_count];
return colors_table[c];
}
/************* .cpp *************/
extern const vec3 colors_table[colors_count] = {
vec3(255, 0, 0), // red
vec3(0, 0, 255), // blue
vec3(0, 255, 0), // green
};
You didn't write anything about purpose of using templates so I just eliminated them. If you explain more then I will help maybe.
// EDIT
It's very simple and very fast.
In c++, enum values are not just some identifiers, they are numbers. If you don't specify other they will be fallowing numbers starting from 0: 'red' is 0, 'blue' is 1, 'green' is 2 and 'colors_count' is 3 (see http://www.google.com/search?q=c%2B%2B+enum).
You can use these numbers to index an array. Then you simply pick an item from an array at given index.
You could just use a std::map<color, vec>:
class ColorClass {
private:
std::map<color, vec> colors;
// ... etc ...
And then you have a big init function that sets it up:
colors["red"] = new vec(0xFF, 0x00, 0x00);
colors["blue"] = new vec(0x00, 0xFF, 0x00);
// ... etc ...
And then your getColor function is just:
return colors[color];
Done!