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

StackOverflow https://stackoverflow.com/questions/514194

  •  21-08-2019
  •  | 
  •  

Вопрос

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

Есть какие-нибудь мысли?

Это было полезно?

Решение

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

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

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

Другие советы

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

enum Fruit {

    ORANGE = 0,
    BANANA = 1

};

с

namespace Fruit {

    enum { //no enum name needed

        ORANGE = 0,
        BANANA = 1

    };

};

...

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

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

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

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

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

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

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

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

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

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

if( firstColor == secondColor )
....

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

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

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


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 .это более полезно в большом проекте, когда вы не знаете, какие перечисления есть в другом классе.

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

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

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

Лично я думаю, что это ошибка компилятора.Я использую C ++ уже много времени.К сожалению, в 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.Без квалификаторов все компилируется.

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

Я отключил это конкретное предупреждение.Я уверен, что людям эта идея не понравится, но некоторые могут быть благодарны..

#pragma warning( disable : 4482 )
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top