Friday, October 14, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 2 topics

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: