Подтвердить что ты не робот

Использование enum внутри типов - Предупреждение компилятора C4482 С++

Я использую полное имя переименования внутри метода в одном из моих классов. Но я получаю предупреждение о компиляторе, в котором говорится: "Предупреждение C4482: используется нестандартное расширение: enum" Foo "используется в квалифицированном имени". В С++ нам нужно использовать перечисления без квалифицированного имени? Но ИМО, что выглядит уродливо.

Любые мысли?

4b9b3361

Ответ 1

Да, перечисления не создают новое "пространство имен", значения в перечислении напрямую доступны в окружении. Итак, вы получаете:

enum sample {
  SAMPLE_ONE = 1,
  SAMPLE_TWO = 2
};

int main() {
  std::cout << "one = " << SAMPLE_ONE << std::endl;
  return 0;
}

Ответ 2

Чтобы сделать его чистым, замените:

enum Fruit {

    ORANGE = 0,
    BANANA = 1

};

с

namespace Fruit {

    enum { //no enum name needed

        ORANGE = 0,
        BANANA = 1

    };

};

...

int f = Fruit::BANANA; //No warning

Ответ 3

Пока он отвечает на вопрос, он не учитывал, как я всегда использовал перечисления. Несмотря на то, что они просто больше или меньше имен для чисел, я всегда использовал их для определения типов, которые могут иметь только определенные значения.

Если перечисление является частью класса, то это помогает потребителям четко идентифицировать ссылку перечисления:

class Apple {
  enum Variety {
    Gala,
    GoldenDelicious,
    GrannySmith,
    Fuji
  }
  ...
};

Затем потребители смогут объявлять экземпляры перечисления, передавать как параметры и определять их при ссылке на один из типов.

unsigned int GetCountOfApples( Apple::Variety appleVariety );
...
fujiCnt = GetCountOfApples( Apple::Fuji );

Иногда вы хотите перечислить за пределами класса или двух перечислений в одном классе, и вы можете сделать что-то вроде того, что было у Поя. Однако вы не сможете ссылаться на тип перечисления, поэтому просто назовите его.

namespace Color {
  enum ColorEnum {
    Blue,
    Red,
    Black
  };

Теперь использование перечисления и значений будет работать следующим образом:

Color::ColorEnum firstColor = Color::Blue;
Color::ColorEnum secondColor = Color::Red;

if( firstColor == secondColor )
....

Теперь, если в них будут разные перечисления с одинаковым именем, они всегда будут соответствовать типу. Тогда вы могли бы справиться с вопросом, о котором спрашивает Гамбор.

BananaColorEnum banCol = BananaColor::Yellow;
TomatoColorEnum tomCol = TomatoColor::Yellow;

Ответ 4

Да. Концептуально перечисление определяет тип и возможные значения этого типа. Хотя кажется естественным, определить enum foo { bar, baz };, а затем обратиться к foo::baz - это то же самое, что и обращение к int::1.

Ответ 5


namespace Company
{
    typedef int Value;
    enum
    {
        Microsoft= 0,
        APPLE = 1, 
    };
};

namespace Fruit
{
    typedef int Value;
    enum
    {
        ORANGE = 0,
        BANANA = 1,
        APPLE = 2, 
    };
};

...

Fruit::Value f = Fruit::BANANA; //No warning
Company::Value f = Company::APPLE; //is different value then Fruit::APPLE

Это работает с компилятором GCC и MS и Mac. Преимущество состоит в том, что вы можете использовать оператор пространства имен и передавать конфликты. Небольшой недостаток заключается в том, что вместо Fruit вам нужно написать Fruit:: Value. это более полезно в большом проекте, когда вы не знаете, какие перечисления находятся в другом классе.

Если вместо этого можно использовать С++ 11, это намного проще, потому что тогда возможно синтаксис enum:: namespace.

Ответ 6

Самый чистый способ, который я нашел для этого, - это определение перечисления как такового

namespace Samples
{
    enum Value
    {
        Sample1,
        Sample2,
        Sample3
    };
}
typedef Samples::Value Sample;

Затем в определениях функций и переменных вы можете использовать typedef:

void Function(Sample eSample);
Sample m_eSample;

И в вашем .cpp файле вы можете использовать пространство имен для назначения переменных:

void Function(Sample eSample)
{
    m_eSample = Samples::Sample1;
    eSample = Samples::Sample2;
}

Ответ 7

Лично я думаю, что это ошибка компилятора. Я использую С++ много времени. К сожалению, в OP нет образца кода. Толкование перечисления людьми Java было фактически правильным iMO. Моя, была такая...

class Foo {
    enum tMyEnum { eFirstVal = 0, eSecondVal = 1};
    // ...
    tMyEnum m_myVal;
};
void Foo::MyMethod() {
    if(m_myVal == tMyEnum::eFirstVal) {
//  ...
    }
}

Я также пробовал Foo:: tMyEnum:: eFirstVal. Без квалификаторов все скомпилировано.