Как использовать enum из другого класса и файла без повторяющихся областей видимости? С++

Я чувствую, что это простой вопрос, но я, кажется, не нахожу ответа сам. Мне было интересно, есть ли способ использовать перечисление в другом файле без использования области видимости? например Head.h

namespace h{
class Eye{
 enum class State{
  closed = 0, blinking, open, staring, rolling // etc.
 };
 void print(const State &eye);
};
class Body{
  Eye::State eye;
  Eye::State eyesOpen();

};
}

Head.cpp

namespace h{
 void Eye::print(const State &eye){
  switch(eye){
     case Eye::State::closed: cout << "Closed" << endl;
     case Eye::State::blinking: cout << "Blinking" << endl;
     case Eye::State::open: cout << "Open" << endl;

 }

 bool Body::eyesOpen(){
   return eye == Eye::open;
 }
}

Я использую Eye::State более 80 раз в своем классе Body, поэтому мне было интересно, есть ли способ просто указать, что State есть Eye::State, вместо того, чтобы писать это 80 раз?

Редактировать: Eye и Body — два отдельных класса. Просто Body использует объект Eye

Используйте псевдоним обычного типа, using State = Eye::State;

molbdnilo 21.03.2022 17:23

Вам даже не нужен псевдоним типа для любых ссылок другими членами того же класса. State::closed, эт. al., в показанном коде, будет работать как есть.

Sam Varshavchik 21.03.2022 17:25

Имейте в виду, однако, что если вы указываете псевдоним делать таким образом, это должно быть сделано не только для удобства, но тип с псевдонимом должен соответствовать охватывающему типу (или пространству имен). В данном примере это не так; или что означает мигающее тело (Body::State::Blinking)???

Aconcagua 21.03.2022 17:28

Боковое примечание: функция print довольно неудачна, так как она принудительно печатает в std::cout — что, если вы собираетесь печатать, например. файл? Лучше: Реализуйте ostream& operator<<(ostream& s, Eye::State state), тогда вы сможете сделать Eye::State s; std::cout << s; или то же самое для любого другого потока.

Aconcagua 21.03.2022 17:32

@molbdnilo, так что это должно работать, если я поставлю псевдоним вверху пространства имен?

user3710760 21.03.2022 17:45

@SamVarshavchik они находятся в двух разных классах, но в одном пространстве имен

user3710760 21.03.2022 17:45
github.com/Neargye/magic_enum (обратите внимание на ограничения).
Marek R 21.03.2022 17:47

Ну, код, который вы показал в основном использовали Eye::State внутри класса Eye, где комментарий Сэма абсолютно правильный. Тот факт, что ваш текст описывает проблему, не видимую в вашем примере кода, не идеален.

Useless 21.03.2022 18:05

Возможная опечатка, кажется, что Body::eyesOpen возвращает Eye::State в заголовке, но возвращает bool в файле cpp.

Ranoiaetep 21.03.2022 18:19

@molbdnilo Я думаю, если бы Eye был в другом пространстве имен, вы все равно могли бы сделать using State Other::Eye::State;?

franji1 21.03.2022 18:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не помещайте псевдоним типа в начало пространства имен, если это действительно не та логическая область, которую вы хотите.

Если вы просто хотите сохранить ввод Body методов, которые вы не показали, просто

namespace h{
class Body{
  using State = Eye::State;
  State eye;
  State eyesOpen();
};
}

будет работать. Кажется странным, что глаза — единственный орган этого тела, состояние которого имеет значение. Если вам действительно нужно больше состояний органов позже, вы можете удалить псевдоним уровня класса и просто написать

bool Body::eyesOpen() {
  using State = Eye::State;
  return eye == State::open;
}

(что вообще не является улучшением, но представьте, что оно применяется к другим 80 экземплярам, ​​которые вы нам не показали).

спасибо, добавление использования в начале класса сработало!

user3710760 22.03.2022 15:00

Другие вопросы по теме