I need to use enum WrapMode in two differernt classes.
what is the best approach.
1) Declare enum in a namespace in a header file and include in both the classes
2) locally declare the namespace in both the classes separately.
enum TextureWrapMode { Repeat = 0, Clamp = 1};
class My_Texture
{
};
///////////////////////////////////////////////////////////////////////
class Texture
{
};
Since you tagged your question c++11: Don't use enum, use enum class. Namespace issue (and more) solved! Unless I can't use C++11 for some reason, I don't see any reason for using enums anymore.
Other than that, I would put it into a header file if it is used by more than one module.
If you are designing a big project or you have a lot of files where that particular enum is going to be used, so it better to put that enum or, I would say, all the common things like common structure in that .h file and include where you want.
And if you have a single file code that you should declare your enum right after the headers you have declared.
#include <iostream>
using namespace std;
enum suit {
club = 0,
diamonds = 10,
hearts = 20,
spades = 3
} card;
int main()
{
card = club;
cout << "Size of enum variable " << sizeof(card) << " bytes.";
return 0;
}
HOPE IT HELPS
Related
I recently have seen some codes for "using" and then I confused because of I don't know their syntax exactly.
1.
using callable_type = void(__stdcall*)(std::string);
auto Various_native::call_me(callable_type callable)
{
callable("--- from native ---");
}
using ST_CHAR = char;
using namespace System;
In the first two examples "using" plays a role similar to the older "typedef" keyword; it allows you to give a custom name/alias to an existing type, so that in latter code you can use that name (e.g. callable_type) instead of the original name (e.g. void(__stdcall*)(std::string)). That has the advantage of potentially making your code easier to read and/or write, and also the advantage that if you ever decide to change the code to use a different type instead, you only have to modify a single line of code rather than every piece of code that mentions the original type.
The third example (using namespace System;) tells the compiler to automatically look inside the System namespace for identifiers, if no namespace is explicitly specified. So for example if there is a function foo() that was declared inside the System namespace, code after the using namespace System; declaration can simply call foo() rather than having to spell out System::foo() every time.
Have a look at this: https://en.cppreference.com/w/cpp/keyword/using
Here are the ways to use using
/* clasic use: as an improved options to the c keyword typedef
for creating aliases for typenames in the local namespace */
using fullname = std::pair<std::string, std::string>;
using relavently_named_type = std::pair<std::pair<std::string, int>, float>;
fullname name{ "mark", "thompson" };
relavently_named_type variable_name{ { "text", 1 }, 1.0f };
/* importing named symbols to the local namespace */
using std::string, std::array, std::begin, std::end;
array character_array{ 'h','e','l','l','o',' ','w','o','r','l','d', };
string hello_world_string{ begin(character_array), end(character_array) };
std::cout << hello_world_string << '\n';
/* importing all names in a namespace into the local namespace */
using namespace std;
array character_array{ 'h','e','l','l','o',' ','w','o','r','l','d', };
string hello_world_string{ begin(character_array), end(character_array) };
std::cout << hello_world_string << '\n';
/* importing all names from an enum class/struct into the local namespace
(only since c++20) */
enum class material { wood, stone, iron, bronze, glass };
auto without_using = material::wood;
using enum material;
auto with_using = wood;
/* import to other visability from parent class(es) and/or
specify which version of "function" to use when refering to C::function */
class A
{
private:
int function();
};
class B
{
private:
int function();
};
class C : A, B
{
public:
using B::function;
};
Cppreference goes into far more detail but this covers the basic. Your question isn't phrased particulary well but i hope i gave the information you wanted. Generally if you're curios about language features and syntax you can find it on cppreference as long as you know the name. Especially look at their examples.
and I'm new to C++ and I'm wondering if anyone can help me to understand why
enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY
and
enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
are underlined in green? it says it prefers enum class, but when I change it to enum class then
enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY;
enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
EASY becomes underlined in red and
myShipCost is underlined in green, BOMBER_COST underlined in red and CRUISER_COST is underlined in red
const int ALIEN_POINTS = 150;
int aliensKilled = 10;
int score = aliensKilled * ALIEN_POINTS;
cout << "score: " << score << endl;
enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDifficulty = EASY;
enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
cout << "\nTo upgrade my ship to a cruiser will cost "
<< (CRUISER_COST - myShipCost) << " Resource Points.\n";
system("pause");
return 0;
enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = difficulty::EASY;
enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = shipCost::BOMBER_COST;
with enum class, implicit conversion to/from integers is removed, and you have to scope the constants in it.
This is considered an improvement. Explicitly casting it back to an integer still works, but it doesn't happen by accident.
std::cout << "\nTo upgrade my ship to a cruiser will cost "
<< (static_cast<int>(shipCost::CRUISER_COST) - static_cast<int>(myShipCost)) <<
" Resource Points.\n";
system("pause");
return 0;
once you are using enum class, you should rename them:
enum class difficulty { novice, easy, normal, hard, unbeatable };
difficulty myDiffiuclty = difficulty::easy;
enum class shipCost { fighter =25, bomber=30, cruiser = 50 };
shipCost myShipCost = shipCost::bomber;
as the ship part of the name is now in the enum, no need to repeat it in the constant. Similarly, because the names are scoped, you don't have to SHOUT them.
Note, however, if you are just using it to create constants and no intention to create a type, consider using something like:
namespace ship {
namespace cost {
constexpr int fighter = 25;
constexpr int bomber = 30;
constexpr int cruiser = 50;
}
}
now we have ship::cost::fighter as an int that is compile-time calculated, instead of as an enum class.
Now that you understand the difference, from the answers above, I'd like to point out a couple of places where the "new" way of doing things breaks down, and what you can do about it.
Consider this (abbreviated) actual example I ran into, porting some audio software I wrote in C to modern C++ (C++17):
typedef enum sample_type_e {
sample_type_uint16,
sample_type_double
}sample_type_t;
Now, the first thing to know is that the typedef here is no longer required; you can read more about that elsewhere. Moving on...
This code, compiled in Visual Studio 2019, will result in the error you describe.
Now, one approach to fixing this would seem to be to move to the new syntax-- but watch what happens:
enum class SampleType {
uint16,
double
}
Oops.
That's not going to work-- double is a reserved word. Now, you could, in exasperation, do this:
enum class SampleType {
uint16,
type_double
}
...but that's not very consistent, and by the time you get to this:
enum class SampleType {
type_uint16,
type_double
}
...you have arguably achieved the exact opposite of at least one of the purported benefits of this new feature: being terse, where possible, without losing context.
The nuisance in my supposedly-contrived but actually real-world example is that you can't scope a reserved word: they're always reserved. (Tangent point of interest: there are languages where that is never true...)
This is called "being unlucky"; it happens a lot more often than language designers like to admit, and it always comes up when you don't have one of them in the room with you.
So, if something like that happens to come up for you, and you just really don't like what the results of trying to use "class enum" wind up looking like, what do you do?
Well, it turns out you can probably make the entire original problem go away by using another language feature that is considered good practice to use wherever possible: namespacing. If I merely namespace that original declaration (minus the crufty typedef), I get:
namespace audiostuff {
enum sample_type_e {
sample_type_uint16,
sample_type_double
};
};
...and as long as any code using that stuff is either in the same namespace, or has
using namespace audiostuff;
at the top, or, alternately, uses is like this:
audiostuff::sample_type_e my_sample_type_var;
...then, lo and behold, Visual Studio stops complaining-- and other compilers should as well.
The complaint, after all, is about reminding you that you should avoid cluttering up the global namespace-- especially by accident. "class enum" is one way to do that, but using an explicit namespace is as well.
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?
There are several questions on these forums about the inheritance of C++ enums for extending (which is actually the thing without the logic). But what about inheritance just for setting specific values?
Currently, there is something like the following in my code:
//lib_impl.h
enum class X {
a = 13, // these values are
b = 42 // implementation dependent
}
//lib.h
#include "lib_impl.h"
void some_func(X param) {
X x = X::a;
}
I just want to avoid the dependecy of the 'lib' from its implementation. Probably, something other than enums must be used for that. As even in C++11 we have the ability only to declare forward enum name, but not its enumerators:
//lib.h
enum class X { a, b } // this is both declaration and definition, unfortunately
void some_func(X param) {
X x = X::a;
}
//lib_impl.h
#include "lib.h"
enum class X { // redefenition, compilation error
a = 13,
b = 42
}
What is the best compile-time solution for such problems?
--
As it seems to be unimplementable in c++, what is the most common way to resolve such issues? Leave the dependency of the 'lib' from the 'impl' as it is? Probably, 'impl' could be split into two parts, small which will be included before the 'lib.h' and other, bigger, to be included after it. Is it ok or I need to abandon the use of enums in favor of abstract classes?
Expose an enum with nominal values (start with 0, sequential say). Inside your library, remap these values to an internal enum with implementation dependent values (say an array for speed, using the external value as index). Reverse the mapping if you export said enum values to the outside (the reverse mapping will be slower).
I am using fully qualified name of the enum inside a method in one of my class. But I am getting compiler warning which says "warning C4482: nonstandard extension used: enum 'Foo' used in qualified name". In C++, do we need to use enums without the qualified name? But IMO, that looks ugly.
Any thoughts?
Yes, enums don't create a new "namespace", the values in the enum are directly available in the surrounding scope. So you get:
enum sample {
SAMPLE_ONE = 1,
SAMPLE_TWO = 2
};
int main() {
std::cout << "one = " << SAMPLE_ONE << std::endl;
return 0;
}
To make it clean, replace:
enum Fruit {
ORANGE = 0,
BANANA = 1
};
with
namespace Fruit {
enum { //no enum name needed
ORANGE = 0,
BANANA = 1
};
};
...
int f = Fruit::BANANA; //No warning
While sth does answer the question, it didn't address how I've always used enums. Even though they're just more or less names for numbers, I've always used them to define types that can only have certain values.
If the enum is part of the class, then that helps consumers clearly identify an enum reference:
class Apple {
enum Variety {
Gala,
GoldenDelicious,
GrannySmith,
Fuji
}
...
};
Then consumers would be able declare instances of the enum, pass as parameters, and qualify them when referencing one of the types.
unsigned int GetCountOfApples( Apple::Variety appleVariety );
...
fujiCnt = GetCountOfApples( Apple::Fuji );
Sometimes you want an enum outside of a class or two enums in the same class, and you can do something like what Poy had. You won't be able to reference the enum type though, so just name it.
namespace Color {
enum ColorEnum {
Blue,
Red,
Black
};
Now using the enum and values would work like:
Color::ColorEnum firstColor = Color::Blue;
Color::ColorEnum secondColor = Color::Red;
if( firstColor == secondColor )
....
Now if there happens to be different enums with the same name in them, they will always be qualified with what type they are. Then you could handle what gamblor is asking about.
BananaColorEnum banCol = BananaColor::Yellow;
TomatoColorEnum tomCol = TomatoColor::Yellow;
Yes. Conceptually enum defines a type, and the possible values of that type. Even though it seems natural, to define enum foo { bar, baz }; and then refer to foo::baz is the same as referring to int::1.
namespace Company
{
typedef int Value;
enum
{
Microsoft= 0,
APPLE = 1,
};
};
namespace Fruit
{
typedef int Value;
enum
{
ORANGE = 0,
BANANA = 1,
APPLE = 2,
};
};
...
Fruit::Value f = Fruit::BANANA; //No warning
Company::Value f = Company::APPLE; //is different value then Fruit::APPLE
This works on GCC and MS compiler and Mac. And the advantage is that you can use namespace operator and pass conflicts. The little disadvantage is that instead of Fruit, you have to write Fruit::Value. it is more useful in large project when you don't know what enums are in other class.
If it is possible to use C++11 instead, it is much more simple, because the enum::namespace syntax is then possible.
The cleanest way I've found to do this is defining the enum as such
namespace Samples
{
enum Value
{
Sample1,
Sample2,
Sample3
};
}
typedef Samples::Value Sample;
Then in function and variable definitions you can use the typedef:
void Function(Sample eSample);
Sample m_eSample;
And in your .cpp file you can use the namespace to assign variables:
void Function(Sample eSample)
{
m_eSample = Samples::Sample1;
eSample = Samples::Sample2;
}
Personally, I think this is a compiler bug. I've been using C++ for lots of time. Sadly, no sample code in OP. The interpretation of an enum by the Java people was actually correct iMO. Mine, was like this ...
class Foo {
enum tMyEnum { eFirstVal = 0, eSecondVal = 1};
// ...
tMyEnum m_myVal;
};
void Foo::MyMethod() {
if(m_myVal == tMyEnum::eFirstVal) {
// ...
}
}
I also tried, Foo::tMyEnum::eFirstVal. Without the qualifiers, everything compiled.
I had the same problem and I'm not using C++ 11 yet. I much prefer fully qualified namespaces myself too.
I disabled this particular warning. I'm sure people will dislike the idea but some may be thankful..
#pragma warning( disable : 4482 )