On Wed, 2017-04-19 at 10:30 +0100, Jonathan Wakely wrote: > On 19 April 2017 at 09:37, Murray Cumming wrote: > > In the ABI-breaking versions of glibmm and gtkmm, we have recently > > changed the enums to be C++11 "enum class"s. This is generally a > > welcome improvement. > > - Their values are, for instance, Things::ONE, rather than > > THINGS_ONE. > > - Their values do not convert implicitly to other types such as int > > or > > bool, helping the compiler to find some programmer mistakes. > > > > We are also gradually moving the enums inside classes when they are > > typically only used with that class. > > > > However, some of the C enums that we wrap are actually meant to be > > integer constants, so it seems that we cannot and should not use > > "enum > > class" for these. > > How are they used? Are they compared to integers? Are they passed to > gtk APIs that expect integers?
Both. > You can use scoped enums anyway, but you'd need an explicit cast to > an > integer, so it might not be appropriate. Yes, that's what we are doing right now. It's a bit ugly. > > So I wonder what is the most "modern C++" way to do > > this while keeping the new-style syntax. Here are two > > possibilities: > > > > 1. Use old-style enums inside a class: > > > > class ResponseType { > > public: > > enum Enum { > > NONE = -1, > > REJECT = -2, > > ACCEPT = -3, > > ... > > }; > > }; > > You can also use a namespace to give them their own scope, which has > less overhead than a class type (no RTTI for the class, no way for > users to create instances of the class type, or pointers to it, which > would have no purpose if it's just being used to create a new scope > for the enumerators). Good point. I'm leaning towards this at the moment. > > But shouldn't we just avoid old-style enums completely? > > Why? Both types still have uses in modern C++. Old doesn't mean bad. > > N.B. since C++11 you can use the enumeration type's name as a > qualification even for unscoped (i.e. old-style, non-class) enums: > > enum E { Foo, Bar, Baz }; > > auto e = E::Foo; > > So you can use the new syntax even with old-style enums. The problem > is that you're not *required* to do that, you can still just say Foo, > so the names still leak into the surrounding scope. OK. I wouldn't like that. > With a scoped > (i.e. new-style, class) enum the qualification is required. > > > > 2. Use constexpr int constants inside a class: > > > > class ResponseType { > > public: > > constexpr int NONE = -1; > > constexpr int > > REJECT = -2; > > constexpr int ACCEPT = -3; > > ... > > }; > > > > But shouldn't we use some kind of enum to group the values > > together? > > Is their type actually important? Not really. These are generally just ints. > i.e. are these different values of > the same logical type? If yes, then using an enumeration makes sense. > Otherwise just using an enumeration type to create an arbitrary group > doesn't add any benefit. > > The example above looks like these are different values for the same > "thing" so giving them the same type makes sense to me. It allows > overloading on that type, for example. > > Aside: IMHO the shouty ALL_CAPS naming is not good style in C++, see > https://accu.org/index.php/articles/1923 for my reasoning. Yes, I saw that mentioned in the C++ Core Guidelines. I might need to adapt my habits. But that's something to deal with later. -- Murray Cumming murr...@murrayc.com www.murrayc.com _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list