Given a C++11 enum class, nested inside several long- and ugly-named namespaces:
namespace
long_and_ugly
{
enum class
colour
{
red,
green,
blue
};
}
Can aliases be made of the enumeration values? With clang++ 3.5, it is possible to do what follows:
using long_and_ugly::colour; // take all the values into the current namespace
using long_and_ugly::colour::red; // take only 'red' into the current namespace
function_taking_colour_argument( red ); // instead of fully referring to the value
g++ 4.9, however, complains. I can't copy its error message because I can't access the code, but it explicitly complained about the usage of the using directive or declaration. I have also tried this:
using red = long_and_ugly::colour::red;
But it also failed. I'm sorry for not pasting the errors. Nevertheless, I believe you should be able to reproduce it.
Is it possible to declare aliases to enumeration values in standard C++11, or was I using a clang extension?
If it is, what is the correct syntax?
1. Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.
An enumeration is a user-defined type that consists of a set of named integral constants that are known as enumerators. This article covers the ISO Standard C++ Language enum type and the scoped (or strongly-typed) enum class type which is introduced in C++11.
No two enum members can have the same name. Each enum member has an associated constant value.
The problem is that the standard says that you shall not refer to an enumerator inside an enum class when using specifying a using-declaration.
7.3.3p7
Theusing
declaration[namespace.udecl]
(n3337)A using-declaration shall not name a scoped enumerator.
namespace N { enum class E { A }; } using N::E; // legal using N::E::A; // ill-formed, violation of [namespace.udecl]p7
Note: clang
does accept both lines above; here's a relevant bug report.
It's perfectly fine to refer to the actual name of the enum class itself, but trying to refer to one of its enumerators is ill-formed.
The standard says that an alias-declaration can only be used to refer to a type-name, since an enumerator isn't a type, using one in such context is ill-formed.
namespace N { enum class E { A }; } using x = N::E; // legal, `N::E` is a type using y = N::E::A; // ill-formed, `N::E::A` isn't a type
You could declare a constant having whatever-name-of-your-choice initialized with the value you'd like to "alias":
namespace N { enum class E { A }; } constexpr N::E x = N::E::A;
int main () { N::E value = x; // semantically equivalent of `value = N::E::A` }
Sort of:
namespace long_and_ugly {
enum class colour
{
red,
green,
blue
};
}
const colour red = long_and_ugly::colour::red;
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