c++ 枚举范围无法使用 -std=c++98 编译,但可以使用 -std=c++11
c++ enum scope failed to compile with -std=c++98, but ok with -std=c++11
一个简单的程序如下,完全没有c++11语法(e.cpp)
#include<iostream>
using namespace std;
namespace m{
class my{
public:
enum A{
u=1,
v=2,
w=3
};
static A f(A a){
return (A)(a + A::u);
}
};
int main(){
using namespace m;
my::A r=my::f(my::u);
return 0;
}
使用g++4.1.2编译:
e.cpp:17:2: warning: no newline at end of file
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11: error: expected primary-expression before ‘)’ token
e.cpp:11: error: ‘A’ is not a class or namespace
将 g++4.9.2 与 -std=c++98 结合使用
g++ e.cpp -std=c++98
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11:36: error: ‘A’ is not a class or namespace
static A f(A a){return (A)(a + A::u);}
^
但是使用-std=c++11 没问题:
g++ e.cpp -std=c++11
为了使其使用 c++98 进行编译,我将其更改为避免 "A::" 为:
static A f(A a){return (A)(a + u);}
所以似乎在 c++98 下,嵌入的枚举 class 在 class 中无法识别,而在 c++11 中它可以工作。这是枚举分辨率的差异,还是 c++98 标准中的一些先前语法错误?
枚举名称不能用于限定 C++11 之前的枚举数。所以在C++98模式下没有bug,代码格式不正确。
您推断规则已更改是正确的。
C++ 常见问题解答 lists the changes made to enumerations in C++11,并引用了推动这些更改的提案。
枚举值不受枚举类型的限制(在 C++98 或 C++11 中)。在以下示例中:
namespace N {
enum E { X };
}
X
直接在命名空间N
的范围内。它的完全限定标识符将是 ::N::X
.
此行为已被 C++11 更改,其中遵循相同的定义,X
的标识符可以 也 使用 ::N::E::X
引用:
[dcl.enum/11]
An enumerator declared in class scope can be referred to using the class member access
operators (::
, .
(dot) and ->
(arrow)), see 5.2.5. [ Example:
struct X {
enum direction { left=’l’, right=’r’ };
int f(int i) { return i==left ? 0 : i==right ? 1 : 2; }
};
void g(X* p) {
direction d; // error: direction not in scope
int i;
i = p->f(left); // error: left not in scope
i = p->f(X::right); // OK
i = p->f(p->left); // OK
// ...
}
—end example ]
一个简单的程序如下,完全没有c++11语法(e.cpp)
#include<iostream>
using namespace std;
namespace m{
class my{
public:
enum A{
u=1,
v=2,
w=3
};
static A f(A a){
return (A)(a + A::u);
}
};
int main(){
using namespace m;
my::A r=my::f(my::u);
return 0;
}
使用g++4.1.2编译:
e.cpp:17:2: warning: no newline at end of file
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11: error: expected primary-expression before ‘)’ token
e.cpp:11: error: ‘A’ is not a class or namespace
将 g++4.9.2 与 -std=c++98 结合使用
g++ e.cpp -std=c++98
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11:36: error: ‘A’ is not a class or namespace
static A f(A a){return (A)(a + A::u);}
^
但是使用-std=c++11 没问题:
g++ e.cpp -std=c++11
为了使其使用 c++98 进行编译,我将其更改为避免 "A::" 为:
static A f(A a){return (A)(a + u);}
所以似乎在 c++98 下,嵌入的枚举 class 在 class 中无法识别,而在 c++11 中它可以工作。这是枚举分辨率的差异,还是 c++98 标准中的一些先前语法错误?
枚举名称不能用于限定 C++11 之前的枚举数。所以在C++98模式下没有bug,代码格式不正确。
您推断规则已更改是正确的。
C++ 常见问题解答 lists the changes made to enumerations in C++11,并引用了推动这些更改的提案。
枚举值不受枚举类型的限制(在 C++98 或 C++11 中)。在以下示例中:
namespace N {
enum E { X };
}
X
直接在命名空间N
的范围内。它的完全限定标识符将是 ::N::X
.
此行为已被 C++11 更改,其中遵循相同的定义,X
的标识符可以 也 使用 ::N::E::X
引用:
[dcl.enum/11]
An enumerator declared in class scope can be referred to using the class member access operators (
::
,.
(dot) and->
(arrow)), see 5.2.5. [ Example:struct X { enum direction { left=’l’, right=’r’ }; int f(int i) { return i==left ? 0 : i==right ? 1 : 2; } }; void g(X* p) { direction d; // error: direction not in scope int i; i = p->f(left); // error: left not in scope i = p->f(X::right); // OK i = p->f(p->left); // OK // ... }
—end example ]