Topic: overloaded enum operator


Author: johnchx2@yahoo.com (johnchx)
Date: 11 May 2003 06:01:20 -0400
Raw View
"Siemel Naran" <SiemelNaran@KILL.att.net> wrote

> Non-type template parameters must be compile time constants.  Thus an enum
> qualifies.  But what if we have overloaded operator| for the enum?  Will
> using operator| in the template argument list cause an error?  For example,
>
> enum openmode { in=1, out=2 };
>
> template <openmode ALWAYS>
> class Silly;
>
> openmode operator|(openmode lhs, openmode rhs) {
>    return openmode(long(lhs)|long(rhs));
> }
>
> typedef Silly<in|out> MySilly; // is this legal?

It's either illegal, or legal but doesn't do what you want.  FWIW,
most compilers say the former, Comeau says the latter.

Borland, g++ and (I think) MSVC treat in | out as a function call,
invoking your operator|(), and therefore say it's not a constant
expression.

Comeau, OTOH, accepts the code and uses the built-in operator to
evaluate the expression. (At least that's what it appears to
do...there may be something even trickier going on, which eludes me!)

I think treating this as an error is pretty clearly preferable to
accepting it and doing something surprising, so I'd bet that there is
something in the standard that actually requires the latter
(otherwise, why would EDG & Comeau do this?).

But I'm at a loss to say what it is.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Victor Bazarov" <v.Abazarov@attAbi.com>
Date: 9 May 2003 05:49:47 -0400
Raw View
"Siemel Naran" <SiemelNaran@KILL.att.net> wrote...
> Non-type template parameters must be compile time constants.  Thus an enum
> qualifies.  But what if we have overloaded operator| for the enum?  Will
> using operator| in the template argument list cause an error?  For
example,
>
> enum openmode { in=1, out=2 };
>
> template <openmode ALWAYS>
> class Silly;
>
> openmode operator|(openmode lhs, openmode rhs) {
>    return openmode(long(lhs)|long(rhs));
> }
>
> typedef Silly<in|out> MySilly; // is this legal?

Yes.  14.3.2/5.  Integral promotions and integral conversions
are applied.

Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Ben Hutchings <do-not-spam-ben.hutchings@businesswebsoftware.com>
Date: 9 May 2003 05:50:29 -0400
Raw View
In article <runta.66941$cO3.4526801@bgtnsc04-news.ops.worldnet.att.net>,
Siemel Naran wrote:
> Non-type template parameters must be compile time constants.  Thus an enum
> qualifies.  But what if we have overloaded operator| for the enum?  Will
> using operator| in the template argument list cause an error?  For example,
>
> enum openmode { in=1, out=2 };
>
> template <openmode ALWAYS>
> class Silly;
>
> openmode operator|(openmode lhs, openmode rhs) {
>    return openmode(long(lhs)|long(rhs));
> }
>
> typedef Silly<in|out> MySilly; // is this legal?
<snip>

Constant expressions are defined in section 5.19 of the standard.  Paragraph
1 says that "except in sizeof expressions, functions, class objects,
pointers, or references shall not be used" so I think the answer is no.
(If the answer was yes, this would be a defect in the standard because C++
compilers are not meant to be able to run arbitrary code at compile time.)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Jakob Bieling" <netsurf@gmy.net>
Date: 9 May 2003 05:51:47 -0400
Raw View
"Siemel Naran" <SiemelNaran@KILL.att.net> wrote in message
news:runta.66941$cO3.4526801@bgtnsc04-news.ops.worldnet.att.net...
> Non-type template parameters must be compile time constants.  Thus an enum
> qualifies.  But what if we have overloaded operator| for the enum?  Will
> using operator| in the template argument list cause an error?  For
example,
>
> enum openmode { in=1, out=2 };
>
> template <openmode ALWAYS>
> class Silly;
>
> openmode operator|(openmode lhs, openmode rhs) {
>    return openmode(long(lhs)|long(rhs));
> }

    I am not really sure, but I think you will get undefined behaviour if
you are trying to assign a value to an 'enum' variable, for which there is
no identifier.

> typedef Silly<in|out> MySilly; // is this legal?

    No, because the compiler cannot evaluate the expression at compile-time.
If I am not mistaken in the above statement, then I would suggest to make
the template parameter of type 'int'. Then you do not need the operator| for
the enum and you can legally specify "in | out" as the template parameter.

hth
--
jb

(replace y with x if you want to reply by e-mail)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Jakob Bieling" <netsurf@gmy.net>
Date: 9 May 2003 11:53:03 -0400
Raw View
"Sebastian Moleski" <s.moleski@tcu.edu> wrote in message
news:b9bhq9$qah$1@unix2.is.tcu.edu...
> "Siemel Naran" <SiemelNaran@KILL.att.net> wrote in message
> news:runta.66941$cO3.4526801@bgtnsc04-news.ops.worldnet.att.net...
> > Non-type template parameters must be compile time constants.  Thus an
> enum
> > qualifies.  But what if we have overloaded operator| for the enum?
> Will
> > using operator| in the template argument list cause an error?  For
> example,
> >
> > enum openmode { in=1, out=2 };
> >
> > template <openmode ALWAYS>
> > class Silly;
> >
> > openmode operator|(openmode lhs, openmode rhs) {
> >    return openmode(long(lhs)|long(rhs));
> > }
> >
> > typedef Silly<in|out> MySilly; // is this legal?
>
> Probably not because the result of "in | out" is not a compile-time
> constant. I would suggest that in this case you do something like
>
> typedef Silly<openmode(int(in) | int(out))> MySilly;
>
> Ugly but it works.

    But is it legal? You are forcing an 'int' value to a type of enum, for
which that enum does not have an identifier.

regards
--
jb

(replace y with x if you want to reply by e-mail)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 10 May 03 18:39:34 GMT
Raw View
In article <b9e9gp$n9j$06$1@news.t-online.com>, Jakob Bieling
<netsurf@gmy.net> writes
>   But is it legal? You are forcing an 'int' value to a type of enum, for
>which that enum does not have an identifier.

Yes, it is perfectly legal, indeed with the values given the C++
Standards requires it to work and was written consciously to ensure that
was the case.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]




Author: johnchx2@yahoo.com (johnchx)
Date: 10 May 03 18:39:42 GMT
Raw View
"Jakob Bieling" <netsurf@gmy.net> wrote

>     But is it legal? You are forcing an 'int' value to a type of enum, for
> which that enum does not have an identifier.

Perfectly legal (7.2/6).  The requirement, roughly, is that the value
fit into the smallest bitset that is needed to represent any of the
enumerators.

I believe that this is allowed in order to support the long-standing
use of enums in C as names for particular bit "flags" which could be
bitwise-or'ed together.  In C++, an enumeration can take on any value
which is the result of bitwise or-ing any of its enumerators.

As an aside, converting a value that doesn't "fit" in this way results
in an unspecified value (but not undefined behavior).

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]




Author: John Potter <jpotter@falcon.lhup.edu>
Date: 10 May 03 18:39:49 GMT
Raw View
On 9 May 2003 11:53:03 -0400, "Jakob Bieling" <netsurf@gmy.net> wrote:

> "Sebastian Moleski" <s.moleski@tcu.edu> wrote in message
> news:b9bhq9$qah$1@unix2.is.tcu.edu...


> > > enum openmode { in=1, out=2 };

Valid values are 0 1 2 3.

> > Probably not because the result of "in | out" is not a compile-time
> > constant. I would suggest that in this case you do something like
> >
> > typedef Silly<openmode(int(in) | int(out))> MySilly;
> >
> > Ugly but it works.

>     But is it legal? You are forcing an 'int' value to a type of enum, for
> which that enum does not have an identifier.

It does not need an enumerator, only few enough bits.  The bitwise or of
any number of enumerators is always a valid value for the enum.  7.2/6.

John

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]




Author: "Sebastian Moleski" <s.moleski@tcu.edu>
Date: 08 May 03 17:57:37 GMT
Raw View
"Siemel Naran" <SiemelNaran@KILL.att.net> wrote in message
news:runta.66941$cO3.4526801@bgtnsc04-news.ops.worldnet.att.net...
> Non-type template parameters must be compile time constants.  Thus an
enum
> qualifies.  But what if we have overloaded operator| for the enum?
Will
> using operator| in the template argument list cause an error?  For
example,
>
> enum openmode { in=1, out=2 };
>
> template <openmode ALWAYS>
> class Silly;
>
> openmode operator|(openmode lhs, openmode rhs) {
>    return openmode(long(lhs)|long(rhs));
> }
>
> typedef Silly<in|out> MySilly; // is this legal?

Probably not because the result of "in | out" is not a compile-time
constant. I would suggest that in this case you do something like

typedef Silly<openmode(int(in) | int(out))> MySilly;

Ugly but it works.

sm



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]




Author: "Siemel Naran" <SiemelNaran@KILL.att.net>
Date: 05 May 03 19:39:45 GMT
Raw View
Non-type template parameters must be compile time constants.  Thus an enum
qualifies.  But what if we have overloaded operator| for the enum?  Will
using operator| in the template argument list cause an error?  For example,

enum openmode { in=1, out=2 };

template <openmode ALWAYS>
class Silly;

openmode operator|(openmode lhs, openmode rhs) {
   return openmode(long(lhs)|long(rhs));
}

typedef Silly<in|out> MySilly; // is this legal?

--
+++++++++++
Siemel Naran



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]