简体   繁体   English

C ++ typedef和enums

[英]C++ typedefs and enums

I am trying to introduce an alias for an enum in one namespace into another namespace. 我试图将一个名称空间中的枚举别名引入另一个名称空间。 While I can declare a variable of the aliased type, the compiler (gcc 4.1.2) will not recognize any of the enumeration's values. 虽然我可以声明别名类型的变量,但编译器(gcc 4.1.2)将无法识别任何枚举值。

namespace A
{
    enum a { One = 1, Two = 2 };
}

namespace B
{
    typedef enum A::a b;
};

A::a a_value = A::One;   // Pretty standard
B::b b_value = B::One;   // Does not work
B::b c_value = A::One;   // Clearly B is a typedef for A

int main (int argc, const char *argv[])
{
   return 0;
}

The compiler error is 编译器错误是

test.cc:12: error: 'One' is not a member of 'B'. test.cc:12:错误:'One'不是'B'的成员。

While the enum type is accessible in B through b , the values are not and must be brought in explicitly: 虽然可以在Bb访问枚举类型,但值不是并且必须明确地引入:

namespace B {
    typedef A::a b;
    using A::One;
}

I don't think there's a way to bring them all in without separate using statements for each unless you do using namespace A; 除非你using namespace A;否则我认为除非你using namespace A;否则有一种方法可以将它们全部带入,而不using单独的using语句 or put the enum in an inline namespace and have a using statement for that. 或者将枚举放在内联命名空间中并为其设置using语句。 The latter might be preferable if you're worried about bringing in all of A and would still like to use the enum values with just A::value . 如果您担心引入所有A并且仍然希望使用仅具有A::value的枚举值,则后者可能更可取。 Here's an example: 这是一个例子:

namespace A
{
    inline namespace en {
        enum a { One = 1, Two = 2 };
    }

    enum c {Three};
}

namespace B
{
    using namespace A::en;
    typedef A::a b;
}

A::a a_value = A::One; // works; things in en are still visible in A
B::b b_value = B::One; // works; en was brought into B
B::b c_value = A::One; // works
A::c meh = B::Three; //fails; only en was brought into B

Be aware that inline namespaces were introduced in C++11, which GCC 4.1.2 has no support for. 请注意,在C ++ 11中引入了内联命名空间,GCC 4.1.2不支持。 If you can, I would strongly recommend upgrading. 如果可以,我强烈建议升级。 The latest stable release is 4.8.1. 最新的稳定版本是4.8.1。

C++ prior to C++11 does not offer any (simple) solution for that problem. C ++ 11之前的C ++没有为该问题提供任何(简单)解决方案。 In C++11, you may declare the enum scoped, using the following syntax: 在C ++ 11中,您可以使用以下语法声明枚举范围:

enum struct a { /* .... */ };  // the class keyword may also be used

The effect is to make enumerators (the constants) scoped within the enum type itself, ie. 效果是使枚举器 (常量)在enum类型本身范围内,即。 the notation to access the constants of a becomes a::One for instance. 符号访问的常量a变成a::One为实例。 Because these now belong to the enum type, and not the namespace, you may easily import them along with the enum into another namespace with a typedef. 因为它们现在属于枚举类型而不是命名空间,所以您可以轻松地将它们与枚举一起导入另一个带有typedef的命名空间。 Note however that scoped enum values may not be promoted to int as easily as with regular enums. 但请注意,scoped enum值可能不像常规枚举那样容易地提升为int

namespace A {
    enum class a { One = 1, Two = 2 };
}

namespace B {
    typedef  A::a b;
}

A::a a_value = A::One;
B::b b_value = B::One;  // Now this works
B::b c_value = A::One;   // Clearly B is still a typedef for A

int main (int argc, const char *argv[]) {
   return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM