66

我在我的一个类的方法中使用枚举的完全限定名称。但我收到编译器警告,上面写着“警告 C4482: nonstandard extension used: enum 'Foo' used inqualified name”。在 C++ 中,我们是否需要使用没有限定名的枚举?但是IMO,这看起来很难看。

有什么想法吗?

4

8 回答 8

59

是的,枚举不会创建新的“命名空间”,枚举中的值在周围范围内直接可用。所以你得到:

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

int main() {
  std::cout << "one = " << SAMPLE_ONE << std::endl;
  return 0;
}
于 2009-02-05T01:46:20.130 回答
39

要使其清洁,请更换:

enum Fruit {

    ORANGE = 0,
    BANANA = 1

};

namespace Fruit {

    enum { //no enum name needed

        ORANGE = 0,
        BANANA = 1

    };

};

...

int f = Fruit::BANANA; //No warning
于 2011-08-20T13:25:18.467 回答
15

虽然某事确实回答了这个问题,但它并没有解决我一直如何使用枚举的问题。尽管它们或多或少只是数字的名称,但我一直使用它们来定义只能具有某些值的类型。

如果枚举是类的一部分,那么这有助于消费者清楚地识别枚举引用:

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

然后消费者将能够声明枚举的实例,作为参数传递,并在引用其中一种类型时限定它们。

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

有时你想要一个类之外的枚举或同一个类中的两个枚举,你可以做一些像 Poy 那样的事情。但是,您将无法引用枚举类型,因此只需命名即可。

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;
于 2012-04-13T15:12:17.320 回答
12

是的。从概念上讲,枚举定义了一种类型,以及该类型的可能值。尽管看起来很自然,但定义enum foo { bar, baz };然后引用与引用foo::baz是相同的int::1

于 2009-02-05T19:59:00.233 回答
9

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::Value 而不是 Fruit。当您不知道其他类中的枚举是什么时,它在大型项目中更有用。

如果可以改用 C++11,那就简单多了,因为 enum::namespace 语法是可能的。

于 2012-09-11T19:37:07.330 回答
7

我发现这样做的最干净的方法是这样定义枚举

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;
}
于 2012-08-08T20:31:43.420 回答
1

就个人而言,我认为这是一个编译器错误。我已经使用 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。没有限定符,一切都会编译。

于 2015-10-19T18:16:14.793 回答
0

我有同样的问题,我还没有使用 C++ 11。我自己也更喜欢完全限定的命名空间。

我禁用了这个特定的警告。我敢肯定人们会不喜欢这个主意,但有些人可能会心存感激。

#pragma warning( disable : 4482 )
于 2018-03-08T01:03:08.063 回答