Question

utiliser la déclaration ne semble pas fonctionner avec le type enum

class Sample{
public:
enum Colour { RED,BLUE,GREEN};
}

using Sample::Colour;

ne fonctionne pas !! Avons-nous besoin d'ajouter une déclaration using pour chaque énumérateur de type enum? comme ci-dessous

using sample::Colour::RED;
Était-ce utile?

La solution

Une classe ne définit pas un espace de noms, donc & "utiliser &"; n'est pas applicable ici.

Vous devez également rendre l’énumération publique.

Si vous essayez d'utiliser l'énum dans la même classe, voici un exemple:

class Sample {
 public:
  enum Colour { RED, BLUE, GREEN };

  void foo();
}

void Sample::foo() {
  Colour foo = RED;
}

Et pour y accéder sans la classe:

void bar() {
  Sample::Colour colour = Sample::RED;
}

Autres conseils

Pour ajouter à la answer de Stevela, le problème avec le code d'origine est que vous fait référence à un membre, mais la déclaration using n'est pas elle-même une déclaration de membre:

7.3.3 / 6 a:

  

Une déclaration using pour un membre de la classe   doit être une déclaration de membre.

Pour mettre cela en évidence, l'exemple suivant fonctionne:

class Sample
{
public:
  enum Colour { RED,BLUE,GREEN};
};

class Derived : public Sample
{
public:
  using Sample::Colour;  // OK
};

Enfin, comme l'a souligné Igor Semenov, ici , même si vous déplacez le Enum definition dans un espace de noms, autorisant ainsi la déclaration using, la déclaration using déclarera uniquement le nom du type enum dans l’espace de nom (la référence standard 2003 est 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
}

Types de base dépendants

Pour permettre les spécialisations partielles et explicites, lorsque le compilateur analyse un modèle de classe, il n'effectue aucune recherche dans les classes de base dépendantes. Par conséquent, la variante suivante avec Sample en tant que modèle ne compile pas:

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;
  }
};

Le problème est que Derived::Colour est traité comme un objet par le compilateur (14.6 / 2):

  

Un nom utilisé dans une déclaration ou une définition de modèle et dépendant d'un paramètre de modèle est supposé ne pas nommer un type, sauf si la recherche de nom applicable trouve un nom de type ou si le nom est qualifié par le mot-clé typename.

En regardant les deux conditions pour que le nom soit un type:

  1. La recherche de Colour ne trouve pas de type car la base dépendante Sample<T> n'est pas recherchée.
  2. Le nom n'est pas qualifié par typename

L'exemple nécessite donc le <=> mot clé:

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;
  }
};

Remarque: La version 98 de la norme n'autorisait pas <=> à être utilisé avec une déclaration using. Le correctif ci-dessus n'était donc pas possible. Voir Accès aux types à partir de classes de base dépendantes et CWG11 .

Norme C ++, 7.3.3.1:

  

Le nom du membre spécifié dans un   using-declaration est déclaré dans le   région déclarative dans laquelle le   using-declaration apparaît. [ Remarque:   seul le nom spécifié l'est   déclaré; spécifiant une énumération   nom dans une déclaration using ne   déclarer ses recenseurs dans le   using-declaration & # 8217; s déclarative   Région. & # 8212; note de fin]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top