используя объявление с enum? - PullRequest
6 голосов
/ 13 января 2009

использование объявления не работает с типом enum

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

using Sample::Colour;

не работает !! мы должны добавить использование объявления для каждого перечислителя типа enum? как ниже

using sample::Colour::RED;

Ответы [ 3 ]

10 голосов
/ 13 января 2009

Класс не определяет пространство имен, поэтому «использование» здесь не применимо.

Кроме того, вам нужно сделать enum общедоступным.

Если вы пытаетесь использовать enum в одном классе, вот пример:

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

  void foo();
}

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

И чтобы получить к нему доступ без класса:

void bar() {
  Sample::Colour colour = Sample::RED;
}
8 голосов
/ 13 января 2009

Чтобы добавить к ответу Stevela , проблема с исходным кодом заключается в том, что вы ссылаетесь на члена, но само объявление об использовании не является объявлением члена:

7.3.3 / 6 имеет:

Объявление использования для члена класса должна быть декларацией участника.

Чтобы подчеркнуть это, работает следующий пример:

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

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

Наконец, как указал Игорь Семенов здесь , даже если вы переместите определение enum в пространство имен, тем самым разрешая объявление using, объявление using будет только объявлять имя типа enum в пространство имен (ссылка на стандарт 2003 года - 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
}

Зависимые базовые типы

Чтобы разрешить частичные и явные специализации, когда компилятор анализирует шаблон класса, он не выполняет никаких поисков в зависимых базовых классах. В результате следующий вариант с примером в качестве шаблона не компилируется:

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

Проблема в том, что Derived::Colour обрабатывается компилятором как объект (14.6 / 2):

Предполагается, что имя, используемое в объявлении или определении шаблона и зависящее от параметра-шаблона, не называет тип, если только применимый поиск имени не найдет имя типа или имя не будет определено ключевым словом typename.

Рассматривая два условия, чтобы имя было типом:

  1. Поиск для Colour не находит тип, поскольку не выполняется поиск в зависимой базе Sample<T>.
  2. Имя не уточняется typename

Поэтому в примере необходимо ключевое слово typename:

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

Примечание: Версия стандарта '98 не позволяла использовать typename с объявлением об использовании, поэтому вышеприведенное исправление было невозможно. См. Доступ к типам из зависимых базовых классов и CWG11 .

5 голосов
/ 13 января 2009

C ++ Standard, 7.3.3.1:

Имя члена, указанное в декларация использования объявлена ​​в декларативный регион, в котором появляется декларация использования. [ Заметка: только указанное имя заявленному; указание перечисления имя в объявлении об использовании не объявить свои счетчики в декларация об использовании область, край. —Конечная записка]

...