- Best way to use enum with classes - 24 Updates
- Stripping cast from macro - 1 Update
JiiPee <no@notvalid.com>: Oct 14 01:22PM +0100 On 14/10/2016 13:18, Jerry Stuckle wrote: >> Its possible another kind of Direction enum would be in another class in >> the future, yes. That option must be left open. > In that case you should have it as a global enum or possibly a class itself. So your logic is here that is the class is the only one who use the enum then put it inside the class.. otherwise outside the class (if somebody outside the class needs to use it)? |
JiiPee <no@notvalid.com>: Oct 14 01:26PM +0100 On 14/10/2016 13:16, 4ndre4 wrote: >> only? > It's a matter of scope: > - does it need to be known outside the class? Yes -> outside. No -> inside. class SpecialVehicle { public: enum Direction { North, East, South, West }; ######## Ok so if I have: SpecialVehicle veh1; and use it (outside the class SpecialVehicle , like in main()): veh1.move(SpecialVehicle::North); Then , becouse we call the enum from outside, this should better be: veh1.move(Direction ::North); and Direction is defined outside class SpecialVehicle. ? |
JiiPee <no@notvalid.com>: Oct 14 01:28PM +0100 On 14/10/2016 13:15, 4ndre4 wrote: >> Direction_West >> }; > With all due respect, this is horrible :) I used to do similar thing (befofe class-enum), ... but I would do: enum Direction { DIR_NORTH, DIR_EAST }; but I am not really doing that anymore :). |
JiiPee <no@notvalid.com>: Oct 14 01:46PM +0100 On 14/10/2016 02:00, JiiPee wrote: > { > public: > ... The problem I have with this approach (which people seem to suggest is the best) is that if I use enum as an array index: int arr[North]; with enum class this does not work but i have to do: int arr[static_cast<int>(Direction::North)]; So I have to put that staticcast to everywhere where I use it as an index. Dont you agree that this: int arr[North]; is much more readable? So if I intend to use enum a lot as an index, then is it better to just use the old enum? |
Hergen Lehmann <hlehmann.expires.5-11@snafu.de>: Oct 14 02:51PM +0200 Am 14.10.2016 um 14:26 schrieb JiiPee: > SpecialVehicle veh1; > and use it (outside the class SpecialVehicle , like in main()): > veh1.move(SpecialVehicle::North); I would consider this as "inside", because the enum is only used when making calls to SpecialVehicle. Hence - enum only used in conjunction with a specific class => put it inside that class to illustrate its purpose. - enum may be of use elsewhere => put it outside. When the enum is outside of a class, you should always use "enum class" to ensure type safety and avoid name collisions. When the enum is inside a class, it's a matter of taste. Personally, i prefer using "enum class" whenever possible. It provides better type safety and allows the use of natural value names without having to fear collisions. This becomes all the more important, if the enum has more than just a few values. Hergen |
JiiPee <no@notvalid.com>: Oct 14 02:08PM +0100 On 14/10/2016 13:51, Hergen Lehmann wrote: > When the enum is inside a class, it's a matter of taste. Personally, i > prefer using "enum class" whenever possible. It In my case i use enum a lot as an index, so enum class would make it more difficult to use it as an index |
Cholo Lennon <chololennon@hotmail.com>: Oct 14 10:08AM -0300 On 10/14/2016 09:28 AM, JiiPee wrote: > DIR_NORTH, > DIR_EAST > }; Well, it's a matter of taste and surely not all here are going to agree with me, but names with all capital letters are generally recommended for macros only. In my case I'd write dirNorth, dirEast, etc -- Cholo Lennon Bs.As. ARG |
JiiPee <no@notvalid.com>: Oct 14 02:09PM +0100 On 14/10/2016 13:51, Hergen Lehmann wrote: > When the enum is inside a class, it's a matter of taste. Personally, i > prefer using "enum class" whenever possible. would you use enum class even if you use enum a lot as an array index? then you have to do static casts.... |
JiiPee <no@notvalid.com>: Oct 14 02:11PM +0100 On 14/10/2016 14:08, Cholo Lennon wrote: > In my case I'd write dirNorth, dirEast, etc I dont use capitals anymore, but isnt it DirNorth better? I think that is what many recommend |
Hergen Lehmann <hlehmann.expires.5-11@snafu.de>: Oct 14 03:10PM +0200 Am 14.10.2016 um 14:46 schrieb JiiPee: > The problem I have with this approach (which people seem to suggest is > the best) is that if I use enum as an array index: > int arr[North]; Using an enum as an array index is very bad practice anyway, because there is no guarantee, that the enum stays within the array limits. Someone might add an additional value later, and everything goes into pieces. You should use at least std::vector, which provides bounds checking... > with enum class this does not work but i have to do: > int arr[static_cast<int>(Direction::North)]; ... or probably even std::map, which also solves having to cast an "enum class" index. Hergen |
Paavo Helde <myfirstname@osa.pri.ee>: Oct 14 04:41PM +0300 On 14.10.2016 16:09, JiiPee wrote: >> prefer using "enum class" whenever possible. > would you use enum class even if you use enum a lot as an array index? > then you have to do static casts.... No. Using static_cast reduces readability and can potentially also hide bugs when code changes. So using it more often than needed is not good. Alternatively, yoy could wrap the array in your own class and provide operator[] taking your enum class, and do the static_cast once only in the operator[]. This has the extra benefit that it forces the caller to use enums uniformly. Cheers Paavo |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 14 03:48PM +0200 On 14.10.2016 03:00, JiiPee wrote: > private: > Direction m_curDirection; > }; Well, I usually define an old-fashioned conversion-happy enum inside a struct, like this: struct Direction { enum Enum { north, east, south, west, _ }; static constexpr int n_values = _; }; Then you can say things like int blah[Direction::n_values] = {}; and void foo( Direction::Enum const d ) { if( d == Direction::south ) {} } and in Special_vehicle you can avoid having to qualify those values, class Special_vehicle : private ::Direction // enum values directly available { public: }; The C++11 enum variants also provide the ability to qualify names of values, which is necessary when two or more enums have the same value names, but it comes at the cost of no implicit conversion to integer. Your comments about "safety" seem to indicate that you don't want that implicit conversion. However, I find that things generally get impractical without it. ;-) Cheers & hth., - Alf |
JiiPee <no@notvalid.com>: Oct 14 02:51PM +0100 On 14/10/2016 14:41, Paavo Helde wrote: > No. Using static_cast reduces readability and can potentially also > hide bugs when code changes. So using it more often than needed is not > good. yes, I agree.... its looks too ugly in too many places. > operator[] taking your enum class, and do the static_cast once only in > the operator[]. This has the extra benefit that it forces the caller > to use enums uniformly. hmmm, good suggestion... i ll check this |
JiiPee <no@notvalid.com>: Oct 14 02:55PM +0100 On 14/10/2016 14:10, Hergen Lehmann wrote: >> int arr[static_cast<int>(Direction::North)]; > ... or probably even std::map, which also solves having to cast an > "enum class" index. ye i thought about map, but its slow , isnt it? If I run a for-loop wich these indexes millions of times per second then map would be slow isnt it? Or is map-call as fast as an array call (to acquire the value)? |
"Öö Tiib" <ootiib@hot.ee>: Oct 14 07:09AM -0700 On Friday, 14 October 2016 15:15:36 UTC+3, 4ndre4 wrote: > > Direction_West > > }; > With all due respect, this is horrible :) Good. Then the 'Direction::North' achieved by enum class (that I prefer to enum) is one character more gruesome. :D |
"Öö Tiib" <ootiib@hot.ee>: Oct 14 07:31AM -0700 On Friday, 14 October 2016 15:46:39 UTC+3, JiiPee wrote: > The problem I have with this approach (which people seem to suggest is > the best) is that if I use enum as an array index: > int arr[North]; You use that 'North' as dimension of raw array? That is hard to understand why you need array with 'North' elements. > with enum class this does not work but i have to do: > int arr[static_cast<int>(Direction::North)]; Yes, but may be you did not want to write it. > int arr[North]; > is much more readable? So if I intend to use enum a lot as an index, > then is it better to just use the old enum? No. The 'int arr[North];' is short. However it is not readable. I still don't understand why you needed to declare such array there. The term "readable" means that I can quickly understand what it does; about 'int arr[North];' I have pondered now some time and am about 95% certain that its author (you) made a programming defect because it does not make sense. |
David Brown <david.brown@hesbynett.no>: Oct 14 04:33PM +0200 On 14/10/16 14:46, JiiPee wrote: > int arr[North]; > is much more readable? So if I intend to use enum a lot as an index, > then is it better to just use the old enum? While you cannot put methods in an enum class, you can use it for defining other functions, such as an "ord" function: enum class Direction { north, south, east, west }; int ord(Direction d) { return static_cast<int>(d); } You can also use it for variable templates (C++14): template<typename T> constexpr const int enumSize; template<> constexpr const int enumSize<Direction> = 4; This lets you write code like this: std::array<int, enumSize<Direction>> coords; void t1(void) { coords[ord(Direction::south)] = 3; } |
Paavo Helde <myfirstname@osa.pri.ee>: Oct 14 06:38PM +0300 On 14.10.2016 15:15, 4ndre4 wrote: >> Direction_West >> }; > With all due respect, this is horrible :) AFAIK this style is often used in C for emulating missing scope (namespace/class/enum class) names. |
Jerry Stuckle <jstucklex@attglobal.net>: Oct 14 11:59AM -0400 On 10/14/2016 8:46 AM, JiiPee wrote: > int arr[North]; > is much more readable? So if I intend to use enum a lot as an index, > then is it better to just use the old enum? Which is one reason you might want to consider a class surrounding the enum. You can create methods (often inline) to handle integer values. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Oct 14 12:02PM -0400 On 10/14/2016 8:22 AM, JiiPee wrote: > So your logic is here that is the class is the only one who use the enum > then put it inside the class.. otherwise outside the class (if somebody > outside the class needs to use it)? True. If it is specific to that one class, then put it inside the class. However, if it is general to more than one class, then it should be outside the class. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
JiiPee <no@notvalid.com>: Oct 14 05:14PM +0100 On 14/10/2016 15:31, Öö Tiib wrote: >> int arr[North]; > You use that 'North' as dimension of raw array? That is hard to understand > why you need array with 'North' elements. no sorry, i mean as an index: arr[North] |
JiiPee <no@notvalid.com>: Oct 14 05:15PM +0100 On 14/10/2016 15:33, David Brown wrote: > void t1(void) { > coords[ord(Direction::south)] = 3; > } yes i saw this on the internet. Is this a good idea? |
JiiPee <no@notvalid.com>: Oct 14 05:16PM +0100 On 14/10/2016 16:59, Jerry Stuckle wrote: >> then is it better to just use the old enum? > Which is one reason you might want to consider a class surrounding the > enum. You can create methods (often inline) to handle integer values. yes, am looking into this |
JiiPee <no@notvalid.com>: Oct 14 05:18PM +0100 On 14/10/2016 17:02, Jerry Stuckle wrote: > True. If it is specific to that one class, then put it inside the > class. However, if it is general to more than one class, then it should > be outside the class. But sometimes we dont know about the future. Like for example Direction might be only used in vehicle currently, but later on some other class might use it as well. should we put it outside just in case others use it? Direction is quite general thing, isnt it? |
Tim Rentsch <txr@alumni.caltech.edu>: Oct 14 07:18AM -0700 >> writing in the C++ standard in this area (among others). > const compiles. However, it does not result in compile time constant > value and is not usable as template parameter or in constexpr. I see. Basically the same as the difference between a constant expression and an integer constant expression in C. That makes the C++ rules consistent with the analogous rules in C, FWTIW. >> Out of curiosity, what happens if you run your examples >> with --std=c++11? > Doesn't make a difference. Okay, thank you for the followup. The limitation on "constant but not allowed to be constexpr" expressions strikes me as a shortcoming of C++, considering various implications for possible use cases. So if a vote were being taken I would vote in favor of eliminating the restriction in cases like this. Not that I think my vote is going to be given much weight, but still... :) |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment