A using declaration does not seem to work with an enum type:
class Sample{
public:
enum Colour {RED, BLUE, GREEN};
}
using Sample::Colour;
does not work!
Do we need to add a using declaration for every enumerators of enum type? Like below:
using sample::Colour::RED;
An enum is defined using the enum keyword, directly inside a namespace, class, or structure. All the constant names can be declared inside the curly brackets and separated by a comma. The following defines an enum for the weekdays. Above, the WeekDays enum declares members in each line separated by a comma.
An enumeration type declaration gives the name of the (optional) enumeration tag. And, it defines the set of named integer identifiers (called the enumeration set, enumerator constants, enumerators, or members). A variable of the enumeration type stores one of the values of the enumeration set defined by that type.
In C++ programming, enum or enumeration is a data type consisting of named values like elements, members, etc., that represent integral constants. It provides a way to define and group integral constants.
Enumerations are similar to classes and, you can have variables, methods, and constructors within them.
By now, there's a related question: 'using enum' in C++20.
It looks like C++20 will have the option make a using enum
declaration, thus finally allowing direct access to an enum class' members, like this (source):
enum class fruit {
orange,
apple,
};
struct S {
using enum fruit; // OK, introduces orange and apple into S
};
void f() {
S s;
s.orange; // OK, names fruit::orange
S::orange; // OK, names fruit::orange
}
Of course, that means that inside S
, you will also be able to simply use orange
and apple
instead of fruit::orange
and fruit::apple
.
To add to Steve Lacey's answer, the problem with the original code is that you refer to a member, but the using declaration is not itself a member declaration:
7.3.3/6 has:
A using-declaration for a class member shall be a member-declaration.
To highlight this, the following example does work:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
Finally, as pointed out by Igor Semenov, even if you move the enum definition into a namespace, thereby allowing the using declaration, the using declaration will only declare the name of the enum type into the namespace (the 2003 standard reference is 7.3.3/2).
namespace Sample
{
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
using Sample::BLUE;
void foo ()
{
int j = BLUE; // OK
int i = RED; // ERROR
}
Dependent Base Types
To allow for partial and explicit specializations, when the compiler parses a class template. it does not perform any lookups in dependent base classes. As a result, the following variation with Sample as a template does not compile:
template <typename T>
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
template <typename T>
class Derived : public Sample<T>
{
public:
using Sample<T>::Colour; // What kind of entity is Colour?
Colour foo () // Not OK!
{
return this->RED;
}
};
The problem is that Derived::Colour
is treated as an object by the compiler (14.6/2):
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
Looking at the two conditions for the name to be a type:
Colour
doesn't find a type because the dependent base Sample<T>
is not searched.typename
The example therefore needs the typename
keyword:
template <typename T>
class Derived : public Sample<T>
{
public:
using typename Sample<T>::Colour; // Colour is treated as a typedef-name
Colour foo () // OK
{
return this->RED;
}
};
Note: The 1998 version of the standard didn't allow typename
to be used with a using declaration and so the above fix was not possible. See Accessing types from dependent base classes and CWG11.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With