Para añadir a Stevela de answer, el problema con el código original es que se hace referencia a un miembro, pero el uso de la declaración no es en sí una declaración de miembro:
7.3.3/6 tiene:
Una declaración de uso para un miembro de clase será una declaración de miembro.
Para resaltar esto, el siguiente ejemplo funciona:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
Por último, como se ha señalado por Igor Semenov here, aunque se mueva la definición de enumeración en un espacio de nombres, permitiendo así que el uso de la declaración, la declaración de uso solo declarará el nombre del tipo de enumeración en el espacio de nombre (La referencia estándar de 2003 es 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
}
tipos base dependientes
Para permitir especializaciones parciales y explícitos, cuando el compilador analiza una plantilla de clase que no realiza ninguna consulta en las clases de base dependientes. Como resultado, la siguiente variación con la Muestra como una plantilla no se compila:
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;
}
};
El problema es que Derived::Colour
se trata como un objeto por el compilador (14.6/2):
Se asume que un nombre utilizado en una declaración o definición de plantilla y que depende de un parámetro de plantilla no nombra un tipo a menos que la búsqueda de nombre aplicable encuentre un nombre de tipo o el nombre esté calificado por la palabra clave typename.
En cuanto a las dos condiciones para el nombre de un tipo:
- búsqueda de
Colour
no encuentra un tipo porque la base depende Sample<T>
no se busca.
- El nombre no está calificado por
typename
Por tanto, el ejemplo necesita el typename
palabra clave:
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;
}
};
Nota: La versión 98 de la norma no permitieron typename
para ser utilizado con una declaración using y por lo tanto la corrección anterior no fue posible. Ver Accessing types from dependent base classes y CWG11.
¿Hay alguna otra manera de hacerlo? – yesraaj
No es realmente relevante para su pregunta en sí, pero le recomiendo encarecidamente que no use identificadores mayúsculas para enumeraciones y constantes. Preprocessor #defines son usualmente mayúsculas en C/C++ y ellos -manclarán otros símbolos con el mismo nombre. –
El uso de la resolución de alcance operator :: on enumeraciones (como en "sample :: Color :: RED") es una extensión específica del compilador, no estándar C++. – bk1e