Reputation: 3945
In MyClass
below, enum MyType
is defined inside the class.
In main, I create a variable of MyClass::MyType t
. This compiles fine. However, when I wish to assign it a value such as OPEN, there is a compilation error "OPEN was not declared in this scope"
Firstly it probably doesn't make sense declaring an enum type inside the class and limiting its scope there and then creating a variable of that enum type elsewhere, but I'm just trying to understand what's happening.
In the first place, how am I able to create a variable of MyType
in main when an object hasn't even been created? Are enums and struct types defined in a class like that implicitly static?
Also, the compiler has access to the enum code, so why doesn't it understand "OPEN"? Thanks
#include <iostream>
using namespace std;
class MyClass
{
public:
enum MyType
{
OPEN,
CLOSED
};
struct MyStruct
{
int val1;
int val2;
};
};
int main()
{
MyClass::MyType t;
t = OPEN; // compilation error
return 0;
}
Upvotes: 2
Views: 2892
Reputation: 2674
(In addition to what others wrote)
If supported by the compiler (Since C++ 11),
it is a better practice to use enum class
:
enum class MyType
{
OPEN,
CLOSED
};
"The enum classes (“new enums”, “strong enums”) address three problems with traditional C++ enumerations:
1) Conventional enums implicitly convert to an integer, causing errors when someone does not want an enumeration to act as an integer.
2) Conventional enums export their enumerators to the surrounding scope, causing name clashes.
3) The underlying type of an enum cannot be specified, causing confusion, compatibility problems, and makes forward declaration impossible."
-
In that case, use the syntax:
int main()
{
MyClass c;
MyClass::MyType t;
t = MyClass::MyType::OPEN;
return 0;
}
Upvotes: 1
Reputation: 13134
Each enum-name and each unscoped enumerator is declared in the scope that immediately contains the enum-specifier. Each scoped enumerator is declared in the scope of the enumeration. These names obey the scope rules defined for all names in [basic.scope] and [basic.lookup]. [ Example:
enum direction { left='l', right='r' }; void g() { direction d; // OK d = left; // OK d = direction::right; // OK } enum class altitude { high='h', low='l' }; void h() { altitude a; // OK a = high; // error: high not in scope a = altitude::low; // OK }
— end example ] An enumerator declared in class scope can be referred to using the class member access operators (::, . (dot) and -> (arrow)), see [expr.ref]. [ Example:
struct X { enum direction { left='l', right='r' }; int f(int i) { return i==left ? 0 : i==right ? 1 : 2; } }; void g(X* p) { direction d; // error: direction not in scope int i; i = p->f(left); // error: left not in scope i = p->f(X::right); // OK i = p->f(p->left); // OK // ... }
— end example ]
Upvotes: 0
Reputation: 36
Your enum MyType is inside the class, so its values are expected to be accessed through the class and the enumeration. You are already creating a MyType without instantiating the class, but an example of instantiation through the class is also provided.
class MyClass
{
public:
enum MyType
{
OPEN,
CLOSED
};
struct MyStruct
{
int val1;
int val2;
};
};
int main()
{
MyClass::MyType t; // Already a MyType value!
MyClass c; // Building your class
t = MyClass::MyType::OPEN; // No compilation error
t = c.OPEN; // Accessing enum through instantiated class
return 0;
}
Upvotes: 1
Reputation: 21
Like Remy said. Value OPEN
is a part of MyClass
class and is only reachable in that classes scope. For your compiler to see it and use it you need to acces it through MyClass::OPEN
.
Upvotes: 1