C ++ typedef和enums

时间:2013-06-13 22:05:13

标签: c++

我正在尝试将一个名称空间中的枚举别名引入另一个名称空间。虽然我可以声明别名类型的变量,但编译器(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;
}

编译器错误是

test.cc:12:错误:'One'不是'B'的成员。

2 个答案:

答案 0 :(得分:7)

虽然可以在Bb中访问枚举类型,但值不是并且必须明确显示:

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

我不认为有一种方法可以在没有单独的using语句的情况下将它们全部带入,除非您执行using namespace A;或将枚举放入内联命名空间并为其设置using语句。如果您担心引入所有A并且仍然希望仅使用A::value的枚举值,则后者可能更受欢迎。这是一个例子:

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

请注意,在C ++ 11中引入了内联命名空间,GCC 4.1.2不支持。如果可以,我强烈建议升级。最新的稳定版本是4.8.1。

答案 1 :(得分:0)

C ++ 11之前的C ++没有为该问题提供任何(简单)解决方案。在C ++ 11中,您可以使用以下语法声明枚举范围:

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

效果是使枚举器(常量)在enum类型本身范围内,即。例如,访问a常量的符号变为a::One。因为它们现在属于枚举类型而不是命名空间,所以您可以轻松地将它们与枚举一起导入另一个带有typedef的命名空间。但请注意,范围枚举值可能不会像使用常规枚举一样轻松地提升为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;
}