Эксперименты с пространством имен в защищенной области класса

#c #c 11

Вопрос:

 #include <iostream>

class A
{
public:
    int func();

protected:
    namespace B { enum { D = 0, E = 1 }; }
    namespace C { enum { D = 0, E = 1 }; }
}

int A::func()
{
    int x = A::B::D;
    int y = A::C::E;
    return x   y;
}

int main() {
    A a;
    int x = a.func();
    std::cout << x << std::endl; // 1
    
    return 0;
}
 

Что не так с этим кодом?

Мне просто любопытно и экспериментировать namespace , потому что я хотел бы иметь enums с одинаковыми названиями ценностей.

Я не хочу использовать enum class , потому что я не могу выполнять операции с целыми числами без перегрузки операторов или приведения.

Ответ №1:

Вы не можете объявить пространство имен внутри класса. Вместо этого вы можете использовать структуру, подобную

 #include <iostream>

class A
{
public:
    int func();

protected:
    struct B { enum { D = 0, E = 1 }; };
    struct C { enum { D = 0, E = 1 }; };
};

int A::func()
{
    int x = A::B::D;
    int y = A::C::E;
    return x   y;
}

int main() {
    A a;
    int x = a.func();
    std::cout << x << std::endl; // 1
    
    return 0;
}
 

что вы можете увидеть в этом живом примере.

Ответ №2:

Из стандарта C 14 (определение пространства имен 7.3.1)

2 Каждое определение пространства имен должно отображаться в глобальной области или в области пространства имен

Итак, эти определения пространства имен в области класса (где вы забыли поставить точку с запятой)

 class A
{
public:
    int func();

protected:
    namespace B { enum { D = 0, E = 1 }; }
    namespace C { enum { D = 0, E = 1 }; }
};
^^^
 

являются недействительными.