Есть или было предложение для C++ использовать контекст для коротких значений enum?

Я использую enum class везде в нашем коде. Иногда пространства имен накапливаются, делая код менее читабельным, как это может быть:

_infoSign->setType(ui::InfoSign::Type::Ok);

Я знаю, я мог бы сократить это с using заявление:

using Type = ui::InfoSign::Type;
_infoSign->setType(Type::Ok);

Недостатком using утверждение является собственным определением Type, В случае, если enum имя изменено на Fooэтот код сохранит Type имя и должен быть обновлен вручную.

Swift использует интересный способ обработки значений перечисления:

enum CompassPoint {
    case north
    case south
    case east
    case west
}

func foo(dir: CompassPoint) {
    // ...
}

Для вызова функции компилятор автоматически использует правильный контекст и позволяет в очень короткой форме указать значение перечисления:

foo(.north)

Есть или было предложение для C++ для подобного синтаксиса?

1 ответ

Решение

Для того случая, о котором я знаю, нет аналогичного предложения. То есть, чтобы уменьшить шум при инициализации перечислителей. По стилю он похож на назначенные инициализаторы (новые для C++20), но отчасти против идеи, что перечислители с ограниченным доступом являются... вы знаете, ограниченными.


Гораздо более распространенная проблема классов enum - многословие в выражениях switch. Для этой проблемы есть P1099: Использование Enum, которое уменьшает

std::string_view to_string(rgba_color_channel channel) {
  switch (channel) {
    case rgba_color_channel::red:   return "red";
    case rgba_color_channel::green: return "green";
    case rgba_color_channel::blue:  return "blue";
    case rgba_color_channel::alpha: return "alpha";
  }
}

в

std::string_view to_string(rgba_color_channel channel) {
  switch (my_channel) {
    using enum rgba_color_channel;
    case red:   return "red";
    case green: return "green";
    case blue:  return "blue";
    case alpha: return "alpha";
  }
}

Я полагаю, вы могли бы также написать:

using enum ui::InfoSign::Type;
_InfoSign->SetType(Ok);

Но это не так уж и многословно (если вы не выполняете эту операцию несколько раз в одной и той же области видимости).

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