Область перечисления c ++ не удалось скомпилировать с -std = c ++ 98, но нормально с -std = c ++ 11 - PullRequest
0 голосов
/ 13 сентября 2018

Простая программа, как показано ниже, вообще без синтаксиса 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 встроенный класс enum не распознается внутри класса, тогда как вс ++ 11 это работает.Это разница в разрешении enum или какая-то предыдущая ошибка синтаксиса в стандарте c ++ 98?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Значения перечисления не ограничены типом перечисления (в C ++ 98 или C ++ 11). В следующем примере:

namespace N {
    enum E { X };
}

X находится непосредственно в области имен N. Его полный идентификатор будет ::N::X.

Это поведение было изменено в C ++ 11, где, следуя тому же определению, идентификатор X можно также ссылаться с использованием ::N::E::X:

[dcl.enum/11]

На перечислитель, объявленный в области видимости класса, можно ссылаться с помощью доступа к члену класса операторы (::, . (точка) и -> (стрелка)), см. 5.2.5. [Пример:

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
    // ...
}

- конец примера]

0 голосов
/ 13 сентября 2018

Имя перечисления не может использоваться для квалификации перечислителя до C ++ 11.Таким образом, в режиме C ++ 98 ошибки нет, код просто неверно сформирован.

Вы правы в выводе, что правила были изменены.

FAQ по C ++ перечисляетизменения, внесенные в перечисления в C ++ 11 , и цитирует предложения, приведшие к этим изменениям.

...