2011-05-17 56 views
3
struct A 
{ 
    enum E 
    { 
     FIRST, 
     SECOND 
    }; 
}; 

struct B 
{ 
    typedef A::E E; 
}; 

int main() 
{ 
    B::E e0 = A::FIRST;//OK (this case is clear for me) 
    B::E e1 = A::E::FIRST;//OK (this case is clear for me as well) 
    B::E e2 = B::FIRST;//Compile Error: FIRST is not member of B (Why isn't this allowed? Don't we lose meaning of typedef of enums in this case?) 
    B::E e3 = B::E::FIRST;//Error of compiler (If there were no bug in visual studio 2005 compiler, would this code work?) 
    return 0; 
} 

P.S.代码中的问题。typedefing枚举的问题。和视觉工作室中的错误2005

更新:其实这个错误在VS2010中修复。

回答

5

B::E e3 = B::E::FIRST加入缺失分号后,下式成立:

在C++ 03,仅在第一行(B::E e0 = A::FIRST;)是正确的,另外三个是错误:

B::E e1 = A::E::FIRST; // error: ‘A::E’ is not a class or namespace 
B::E e2 = B::FIRST; // error: ‘FIRST’ is not a member of ‘B’ 
B::E e3 = B::E::FIRST; // error: ‘B::E’ is not a class or namespace 

在C++ 0x,只有第二行(B::E e2 = B::FIRST;)是错误的(FIRST仍然不是B的成员!),其他三个都是正确的。

不是“为什么?”的答案,只是指出手边有两个不同的问题。影响e1和e3的问题的基本原理可能在C++ 0x工作文件中解释。

的变化为至的3.4.3 [basic.lookup.qual]/1第一句中现在说

类或空间成员或枚举的名称可以之后被称为该::范围解析操作

但它常说

类或命名空间成员的名字可以被称为后::范围解析运算符

+0

这就是我正在寻找的标准短语,所以这个definitly *就是对“为什么?”的回答。 :) – Xeo 2011-05-19 22:49:13

2

周围命名空间,也就是struct A的名称空间中仅枚举“溢出”。简单的typedef不会产生struct B的相同效果。


此外,如果您启用警告等级4(/ W4),你会得到这个漂亮的警告:

警告C4482:在使用枚举 'A :: E':使用非标准扩展限定名称

不允许使用A::E::XXX来引用当前标准中的枚举值。

+1

这证实了他的观察,但没有解释为什么C++这样做的原因.... – 2011-05-17 08:21:59

+0

@Tony:目前正在标准中搜索它。 :) – Xeo 2011-05-17 08:30:24

+0

标准并不经常解释事物的基本原理,但祝你好运。干杯。 – 2011-05-17 08:48:49