On 3 May 2023, at 18:40, Giuseppe D'Angelo via Development 
<development@qt-project.org> wrote:

Il 02/05/23 10:58, Volker Hilsheimer via Development ha scritto:
During the header review, but also in API discussions leading up to it, we had 
a few cases where it would have helped if we had clearer guidelines about when 
to use scoped enums, and when not.
Scoped enums have some clear technical advantages (such as better type safety, 
thanks to no implicit conversion to int). And they sometimes result in better 
APIs when enum values don’t have to repeat the enum’s name in order to be clear.

Should we vote on this? To me it's a no brainer: any new enumeration added to 
Qt shall be an enum class.

But sometimes it’s also creating too much verbosity to use a scoped enum (ie. 
Qt::Orientation::Horizontal would perhaps not be an improvement).

I wouldn't consider this tiny bit of extra verbosity a huge impediment. Note 
that Qt::Horizontal is violating the API naming guidelines. It should've been 
called Qt::HorizontalOrientation. How is that now better than 
Qt::Orientation::Horizontal?

No, Qt::Horizontal isn't "unambiguous" so it can't be non-qualified. Does it 
refer to what? Text alignment? Text direction? Layout direction? (Hint: none of 
these.)

These are all straw men.

I’ll quote directly from 
https://wiki.qt.io/API_Design_Principles#Naming_Enum_Types_and_Values
Naming Enum Types and Values

The guiding principle is to avoid name clashes between enum values and to 
ensure readability code with reasonable verbosity.

Enums in Qt/global namespace

New enums in the Qt namespace should always use scoped/strong enumerators by 
default. The scoping/strong typing ensures that there is no conflict if the 
same enum value name is used multiple times:

 namespace Qt
 {
   enum class Color {
     Blue,
     Orange,
     Yellow
   };

   enum class FavoriteColor {
     Yellow,
     Orange
   };
 }

 Color yellow = Qt::Color::Yellow;
 FavoriteColor yellow2 = Qt::FavoriteColor::Yellow;
 yellow2 = Qt::Orange; // error


When using scoped enums additional naming rules (repeating of enum type name 
inside enum value name) for are not necessary.

Enums in classes

Enums inside a class do not have the same problem of names clashing, as they 
are already namespaced within the class.

There are still reasons to prefer scoped enums inside classes, but this should 
be decided on a case by case basis.

If the enum values have a clear relation to the parent class, prefer un-scoped 
enums:

 class TouchPoint
 {
   enum State {
        Pressed,
        Held,
        Released
   };
};

// The context is clear when used outside the class
if (point.state() == TouchPoint::Pressed)
   ...

// As well as when used inside it
if (state() == Pressed)
   ...


Using scoped enums in this case would add redundant line noise:

if (point.state() == TouchPoint::State::Pressed)
   ...
if (state() == State::Pressed)
   ...


Note that the context where the enum is used, such as the name of the getter 
that returns the enum value, might be enough information to make a scoped enum 
redundant.

If the enum values do not have a natural relation to the class name, prefer 
scoped enums, e.g.:

 class QSslCertificate
 {
   enum class PatternSyntax {
        RegularExpression,
        Wildcard,
        FixedString
   };
};

if (syntax == PatternSyntax::Wildcard)
  ...


Another option to avoid the name clash instead of scoped/strong enums is to 
embedded the enum type name into each enum value. This method was extensively 
used in Qt 4 before scoped/strong enums were available.

 class Widget
 {
      enum Corner {
           TopLeftCorner,
           BottomRightCorner,
            …
      };
 };

 tabWidget->setCornerWidget(widget, Widget::TopLeftCorner);
-- 
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to