Доступ к значениям перечисления в C ++ 98 и C ++ 11

У меня есть набор значений enum, определенных в классе «Foo» (ниже).

namespace Fii
{
class Foo
{
struct Bar
{
enum Baz
{
BAZ1,
BAZ2,
BAZ3
};
};
};
};

Я использую структуру, чтобы уменьшить область значений перечисления Baz, а также показать, что есть группа связанных значений.

Моя цель — присвоить значение из типа enum переменной. Используя приведенное выше определение класса, можно сделать это:

Fii::Foo::Bar::Baz myValue = Fii::Foo::Bar::BAZ1 (Works in both C++98 and C++11)

Тем не менее, я чувствую, что:

  • На первый взгляд, MyValue похоже инициализируется как Fii :: Foo :: Bar но это только потому, что enum — это хак для группировки связанных констант в родительском (Бар в этом случае)

Чтобы улучшить готовность, я изменил код для:

namespace Fii
{
class Foo
{
enum Baz
{
BAZ1,
BAZ2,
BAZ3
};
};
};

Используя это новое определение класса, можно сделать это:

Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 (Works in C++11 only)
Fii::Foo::Baz myValue = Fii::Foo::BAZ1 (Should work on C++98 and C++11 - not tested)

Q1) Почему Fii :: Foo :: Bar :: Baz myValue = Fii :: Foo :: Baz :: BAZ1 работает только на C ++ 11?

Q2) В C ++ 98 есть способ написать Fii :: Foo :: Baz myValue = Fii :: Foo :: Baz :: BAZ1 ? Вам разрешено вносить любые изменения в определение класса.

Среда:
— Clang компилятор с поддержкой C ++ 11
— Xcode 4
— Mac OS OS 10.8

5

Решение

Ответ Хуанхопанцы действителен для Q1 …

Q2: В C ++ 98 есть способ написать Fii :: Foo :: Baz myValue = Fii :: Foo :: Baz :: BAZ1? Вам разрешено вносить любые изменения в определение класса.

Что-то вроде:

namespace Fii
{
class Foo
{
class Baz
{
public:
enum E { BAZ1, BAZ2, BAZ3 };
Baz(E e) : e_(e) { }
operator const E() const { return e_; }
private:
E e_;
};
};
}

Пояснение: для Fii::Foo::Baz::BAZ1 быть действительной ссылкой на перечисление в C ++ 03, Baz должен быть namespace или же class/struct/union, Но мы пытаемся создать впечатление, что сам Baz является типом перечисления, причем BAZ1 является одним из доступных значений. Для этого мы должны сделать Baz определяемым пользователем типом (классом / структурой), способным хранить любые перечисления, объявленные в его области видимости. Поэтому мы добавляем элемент данных для записи текущего значения, конструктор для установки значения, оператор для неявного представления значения перечисления, чтобы вам не приходилось кодировать явные ссылки на e_ везде в коде, используя Baz объекты или назвать некоторые get() const функция.

5

Другие решения

C ++ 11 добавляет классы. Он также добавляет новый способ доступа к значениям перечислений старого стиля, который вы видите здесь.

enum Foo { FOO1, FOO2, FOO3 }; // old-style enum

Foo f1 = Foo::FOO1; // OK in C++11, error in C++98.
Foo f2 = FOO1; // OK in C++98 and C++11 (for backward compatibility)
6

По вопросам рекламы [email protected]