Использование перечисления внутри типов - Предупреждение компилятора C4482 C ++
-
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 )