9

我正在尝试将一个命名空间中的枚举的别名引入另一个命名空间。虽然我可以声明别名类型的变量,但编译器(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:错误:“一个”不是“B”的成员。

4

2 回答 2

7

虽然 enum 类型可以在Bthrough中访问b,但这些值不是并且必须显式地引入:

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

我不认为有一种方法可以在没有单独using语句的情况下将它们全部引入,除非您这样做using namespace A;或将枚举放入内联命名空间并为此使用 using 语句。如果您担心引入所有A并且仍然希望将枚举值与 just 一起使用,则后者可能更可取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。

于 2013-06-13T22:12:15.813 回答
0

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

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

效果是使 枚举器(常量)在枚举类型本身的范围内,即。例如,访问常量的符号a成为a::One。因为这些现在属于 enum 类型,而不是命名空间,所以您可以轻松地将它们与 enum 一起导入到另一个具有 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;
}
于 2013-06-13T22:47:43.473 回答