I have created an Enum Class in Unreal C++
#include "GroundDirection.generated.h"
UENUM(BlueprintType)
enum UGroundDirection
{
BOTTOM = 0,
LEFT = 1,
TOP = 2,
RIGHT = 3
};
In C# or Java I could instantiate a copy of this Enum doing something like this:
GroundDirection groundDirection = GroundDirection.BOTTOM;
I thought I could do something similar with Unreal C++
UGroundDirection groundDirection = UGroundDirection.BOTTOM;
However when I do this I get the following error:
error C2228: left of '.BOTTOM' must have class/struct/union
How to I instantiate Enums in light of this error?
I have created an Enum Class in Unreal C++
No, you didn't. You just created a C-style enum.
Also, the UE++ coding standard states that an enum should have an E as a prefix.
So your declaration should actually look like this:
#include "GroundDirection.generated.h"
UENUM(BlueprintType)
enum class EGroundDirection
{
BOTTOM = 0,
LEFT = 1,
TOP = 2,
RIGHT = 3
};
To access the members of the enum, you access them like they are static members of a class:
EGroundDirection direction = EGroundDirection::BOTTOM;
This is, because you are not accessing a member of an instance, but a declaration which is always done by using :: in C++.
BOTTOM isn't a class but an integer. Moreover, UGroundDirection isn't a class/struct/union but an enum, and hence it is kind of considered as a namespace. You shall use :: instead of .
To solve your problem, you shall simply remove UGroundDirection from UGroundDirection groundDirection = UGroundDirection.BOTTOM; and replace it with: int groundDirection = UGroundDirection::BOTTOM
That's all!
In C++, you can use either the "namespace-enum" style or "enum class" style. Both of them will limit the elements in specific domain.
Well, some comments say I didn't proveide the solution.
You can try
#include "GroundDirection.generated.h"
UENUM(BlueprintType)
enum class EGroundDirection
{
BOTTOM = 0,
LEFT = 1,
TOP = 2,
RIGHT = 3
};
or
#include "GroundDirection.generated.h"
UENUM(BlueprintType)
namespace EGroundDirection
{
enum EGroundDirection
{
BOTTOM = 0,
LEFT = 1,
TOP = 2,
RIGHT = 3
};
};
Related
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
Consider the following C++ enumerations:
enum Identity
{
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED = 3
};
enum Status
{
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED = 3
};
The Compiler conflicted the both UNKNOWN items and threw this error:
error: redeclaration of 'UNKNOWN'
I am able to solve this error changing one of the UNKNOWN to UNKNOWN_a, but I would like to do not change the names.
How can I solve this conflict without changing the enum items name?
You can use scoped enumerations for this. This requires C++11 or higher support.
enum class Identity
{
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED =3
};
enum class Status
{
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED =3
};
int main ()
{
Identity::UNKNOWN;
Status::UNKNOW;
}
Live Example
Use scoped enums (C++ 11) - enum classes. They will not pollute the outer scope with duplicate names.
But, you'll need to access the enumerated values with a scope resolution operator - Identity::UNKNOWN, which is not a bad thing.
If using C++11 is not feasible(It really should by now, I mean, it's already 2015), consider using namespaces:
namespace Identity {
enum {
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED =3
};
}
namespace Status {
enum {
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED =3
};
}
But, really, enum class is much better.
This is how I would usually declare such enums (if I don't need something more fancy, like automatic conversions of the enum names to strings, serialization/deserialization etc.):
struct Identities
{
enum Type
{
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED = 3
};
};
typedef Identities::Type Identity;
struct States
{
enum Type
{
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED = 3
};
};
typedef States::Type Status;
// usage
Identity identity = Identities::UNKNOWN;
Status status = States::UNKNOWN;
Works in every C++ version and is type safe as well. Namespaces can be also used instead of structs (but I normally use structs).
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'm adding a enum type to the very few bits of C++ I've learnt so far, but having trouble to set it...Am i missing some fundamentals?
class Rectangle
{
public:
Rectangle();
~Rectangle();
enum rectangle_directions_t {R_LEFT = 0, R_DOWN = 1, R_RIGHT= 2, R_UP = 3, R_NONE = 4};
void setRect(rectangle_directions_t rec_dir) {rectangle_direction = rec_dir;}
private:
rectangle_directions_t rectangle_direction;
};
int main()
{
Rectangle pRect;
pRect.setRect(R_LEFT);
}
Can you not just set a variable of an enum type like any other type? Or am i missing something simple? The error I get is during the "set" in main which says R_LEFT is undefined. Which is odd because I don't usually declare an "int" first if I want to pass it to a method...
The enumeration is defined within your class Rectangle. You need to qualify R_LEFT:
pRect.setRect(Rectangle::R_LEFT);
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 )