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