Topic: The opposite of operator!


Author: "Ronald F. Guilmette" <rfg@rahul.net>
Date: 1995/06/24
Raw View
In article <KANZE.95Jun21103236@slsvhdt.lts.sel.alcatel.de>,
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
>
>I'm glad to see that some commercial organizations are committed to
>quality.  Implicit conversions and strict typing are practically
>contradictary.  (I've just been bitten by the implicit conversion to
>void* in ios.)

It is wrong to say that implicit conversions and strict typing are
_practically_ contradictory.  They _are_ contradictory.  Period.
--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- E-mail: rfg@segfault.us.com ----------- Purveyors of Compiler Test ----
---- finger: rfg@rahul.net ----------------- Suites and Bullet-Proof Shoes -





Author: swf@elsegundoca.ncr.com (Stan Friesen)
Date: 1995/06/22
Raw View
In article <KANZE.95Jun21102910@slsvhdt.lts.sel.alcatel.de>, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> In article <1995Jun20.174711.11531@nlm.nih.gov>
|> bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract) writes:
|> |> The current version of the draft standard has replaced 'operator void *()
|> |> const' with 'operator bool() const'. ...
|>
|> In my copy, this is only in an editorial box.  All of the functions
|> for testing state seem to be missing from the standard proper ...

You must have an older copy.
The on-line draft I am looking at has basic_ios::operator bool() const;
defined as a public member that returns !fail().  (Sections 27.4.4, and
27.4.4.3).

--
swf@elsegundoca.attgis.com  sarima@netcom.com

The peace of God be with you.





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/23
Raw View
In article <DAKzz3.H2F@lcpd2.SanDiegoCA.ATTGIS.COM>
swf@elsegundoca.ncr.com (Stan Friesen) writes:

|> In article <KANZE.95Jun21102910@slsvhdt.lts.sel.alcatel.de>, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> |> In article <1995Jun20.174711.11531@nlm.nih.gov>
|> |> bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract) writes:
|> |> |> The current version of the draft standard has replaced 'operator void *()
|> |> |> const' with 'operator bool() const'. ...
|> |>
|> |> In my copy, this is only in an editorial box.  All of the functions
|> |> for testing state seem to be missing from the standard proper ...

|> You must have an older copy.
|> The on-line draft I am looking at has basic_ios::operator bool() const;
|> defined as a public member that returns !fail().  (Sections 27.4.4, and
|> 27.4.4.3).

Actually, I was looking at the wrong place: ios_base (27.4.3) instead
of basic_ios (27.4.4).  Since all of the other functions I expected
were there...

If I remember the Koenig article correctly, the main reason for not
using int was as follows:

I define a user type MyType.  I `forget' to define (or declare)
operator<<( ostream& , MyType const& ).  I then write:

 cout << someMyType ;

If there is any way to convert someMyType to an int (say, because it
uses the same convention as iostream for `isValid' to int as does
ios), then this statement is legal; both of the objects are converted
to int!  The programmer then has to try and figure out why nothing is
showing up in his output.

According to the article, there actually was a version of iostream
that did have operator int (way back when).  The use of operator void*
was introduced (or reinstated) because of the problems this caused in
the reality.

Since bool is an integral type, it suffers from the same problems.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: ncm@netcom.com (Nathan Myers)
Date: 1995/06/20
Raw View
In article <KANZE.95Jun20171205@slsvhdt.lts.sel.alcatel.de>,
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
>In article <ncmDAG6Aq.CGu@netcom.com> ncm@netcom.com (Nathan Myers)
>writes:
>
>|> It's almost always a big, BIG mistake to define a conversion
>|> to any numeric type, including bool.  Anything that converts to
>|> bool converts to any other numeric type as well, which demolishes
>|> type safety and makes a mess of overloading.
> ...
>|> Actually, if you want to check validity of an object, you're
>|> always much better off saying "if (a.isValid())".

>What do your customers say to this?  I've inserted a few such
>conversion functions despite my personal opinions, `by popular
>demand':-(.

Rogue Wave has succumbed to such requests in the past, and
we have always regretted it (and changed back).  It invariably
broke lots of code, often including that of the people who had
requested the change.

"Implicit conversions have a place, as do reinterpret-casts and
goto statements, but their presence in a user-level class interface
should make one profoundly suspicious."

Nathan Myers
myersn@roguewave.com





Author: bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract)
Date: 1995/06/20
Raw View
James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
: In article <ncmDAG6Aq.CGu@netcom.com> ncm@netcom.com (Nathan Myers)
: writes:

: |> In article <3rs7cu$j7f@ankh.iia.org>,
: |> Micha Berger <aishdas@haven.ios.com> wrote:
: |> >wslade@atlanta.com wrote:
: |> >: However there are many times when I would like to
: |> >: test the opposite and find that the following code
: |> >: is clumsy:
: |> >
: |> >: {
: |> >:   Object a;
: |> >
: |> >:   if (!(!a))
: |> >:    return;
: |> >:   // Do something
: |> >: }

: |> >This is exactly why the "bool" type was introduced. define an
: |> >Object::operator bool(). This would be automatically invoked in an
: |> >if statement like
: |> > if (a)
: |> >     return;

: |> It's almost always a big, BIG mistake to define a conversion
: |> to any numeric type, including bool.  Anything that converts to
: |> bool converts to any other numeric type as well, which demolishes
: |> type safety and makes a mess of overloading.

: |> If you *must* provide such a conversion, provide two -- to bool
: |> and also (e.g.) int, so that if it happens accidentally your
: |> compiler will complain about an ambiguous conversion path.

: This is actually why the iostream classes convert to `void*', instead
: of bool.  Still...  I remember that there was a discussion some time
: back either here or in comp.lang.c++, in which Jamshid Afshar
: convinced me that even `void*' had some problems; his solution was to
: declare an empty private class, just for the type, and return a
: pointer to it.

The current version of the draft standard has replaced 'operator void *()
const' with 'operator bool() const'.  I would imagine that the real reason
the older version of the iostreams library used 'operator void *() const'
is that bool was not originally a built-in type.

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                       Stream International */
/* bob_kline@stream.com               formerly Corporate Software, Inc. */
/* voice: (703) 522-0820 x-311                      fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/





Author: ncm@netcom.com (Nathan Myers)
Date: 1995/06/20
Raw View
In article <3rs7cu$j7f@ankh.iia.org>,
Micha Berger <aishdas@haven.ios.com> wrote:
>wslade@atlanta.com wrote:
>: However there are many times when I would like to
>: test the opposite and find that the following code
>: is clumsy:
>
>: {
>:   Object a;
>
>:   if (!(!a))
>:    return;
>:   // Do something
>: }

>This is exactly why the "bool" type was introduced. define an
>Object::operator bool(). This would be automatically invoked in an
>if statement like
> if (a)
>     return;

It's almost always a big, BIG mistake to define a conversion
to any numeric type, including bool.  Anything that converts to
bool converts to any other numeric type as well, which demolishes
type safety and makes a mess of overloading.

If you *must* provide such a conversion, provide two -- to bool
and also (e.g.) int, so that if it happens accidentally your
compiler will complain about an ambiguous conversion path.

Actually, if you want to check validity of an object, you're
always much better off saying "if (a.isValid())".

Nathan Myers
myersn@roguewave.com





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/06/20
Raw View
>>>>> Nathan Myers <ncm@netcom.com> writes:

> If you *must* provide such a conversion, provide two -- to bool
> and also (e.g.) int, so that if it happens accidentally your
> compiler will complain about an ambiguous conversion path.

Of course, it will also complain if it happens deliberately.

> Actually, if you want to check validity of an object, you're
> always much better off saying "if (a.isValid())".

Or, more tersely, "if (+a)" (requiring, of course, an operator+()).

Jason





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/20
Raw View
In article <ncmDAG6Aq.CGu@netcom.com> ncm@netcom.com (Nathan Myers)
writes:

|> In article <3rs7cu$j7f@ankh.iia.org>,
|> Micha Berger <aishdas@haven.ios.com> wrote:
|> >wslade@atlanta.com wrote:
|> >: However there are many times when I would like to
|> >: test the opposite and find that the following code
|> >: is clumsy:
|> >
|> >: {
|> >:   Object a;
|> >
|> >:   if (!(!a))
|> >:    return;
|> >:   // Do something
|> >: }

|> >This is exactly why the "bool" type was introduced. define an
|> >Object::operator bool(). This would be automatically invoked in an
|> >if statement like
|> > if (a)
|> >     return;

|> It's almost always a big, BIG mistake to define a conversion
|> to any numeric type, including bool.  Anything that converts to
|> bool converts to any other numeric type as well, which demolishes
|> type safety and makes a mess of overloading.

|> If you *must* provide such a conversion, provide two -- to bool
|> and also (e.g.) int, so that if it happens accidentally your
|> compiler will complain about an ambiguous conversion path.

This is actually why the iostream classes convert to `void*', instead
of bool.  Still...  I remember that there was a discussion some time
back either here or in comp.lang.c++, in which Jamshid Afshar
convinced me that even `void*' had some problems; his solution was to
declare an empty private class, just for the type, and return a
pointer to it.

To be truthful, I didn't pay that much attention to it at the time,
because I strongly agree with your following statement.  IMHO, a class
which does not represent a predicate has no business converting
implicitly to a predicate.  (In fact, there are often several
different predicates which could be reasonably used.)

|> Actually, if you want to check validity of an object, you're
|> always much better off saying "if (a.isValid())".

What do your customer's say to this?  I've inserted a few such
conversion functions despite my personal opinions, `by popular
demand':-(.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: barmar@nic.near.net (Barry Margolin)
Date: 1995/06/16
Raw View
In article <3rrq13$h5v@nntp.atlanta.com> wslade@atlanta.com writes:
>What I would really like to do is the following:
>
>{
>  Object a;
>  if (a)
>    return;
>  // Do something
>}

if (a) ...

is defined to be equivalent to

if (a != 0) ...

If you implement Object::operator!=(int) then I think this should be used
to perform your test.
--
Barry Margolin
BBN Planet Corporation, Cambridge, MA
barmar@{bbnplanet.com,near.net,nic.near.net}
Phone (617) 873-3126 - Fax (617) 873-5124





Author: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/06/16
Raw View
wslade@atlanta.com writes:

>I often have a requirement to test whether an object is
>valid or not. {Valid based on some attribute or logic
>within the object}.

>Hence I provide an operator!, which I use as follows

>{
>   Object a;

>   if (!a)
>     return;
>   // Do something
>}


>However there are many times when I would like to
>test the opposite and find that the following code
>is clumsy:

>{
>  Object a;

>  if (!(!a))
>   return;
>  // Do something
>}

>What I would really like to do is the following:

>{
>  Object a;
>  if (a)
>    return;
>  // Do something
>}

How about defining a conversion function for your class? If your
compiler supports bool, use operator bool() const;. Otherwise you
will need a unique conversion to either an integer type or to
void*.





Author: kuehl@uzwil (Dietmar Kuehl)
Date: 1995/06/16
Raw View
Hi,

your question is more appropriate for the newsgroups comp.lang.c++ as
is doesn't discuss the (upcoming) C++ standard but rather some
implementational issue.

wslade@atlanta.com wrote:
: I often have a requirement to test whether an object is
: valid or not. {Valid based on some attribute or logic
: within the object}.
:
: Hence I provide an operator!, which I use as follows

Define an 'operator bool() const' which is used as follows:

    Object a;
    if (a)  do something
    if (!a) do something else (operator! is defined for bool)

If your compiler does not support the type bool use a conversion to in
int instead of a conversion to bool. bool is a relatively new keyword
in C++ and not all current compilers understand it.

dk
--
http://www.informatik.uni-konstanz.de/~kuehl
dietmar.kuehl@uni-konstanz.de
I am a realistic optimist - that's why I appear to be slightly pessimistic





Author: schapel@zonker.cs.ucsb.edu (Steve E. Chapel)
Date: 1995/06/16
Raw View
barmar@nic.near.net (Barry Margolin) writes:

>In article <3rrq13$h5v@nntp.atlanta.com> wslade@atlanta.com writes:
>>What I would really like to do is the following:
>>
>>{
>>  Object a;
>>  if (a)
>>    return;
>>  // Do something
>>}

>if (a) ...

>is defined to be equivalent to

>if (a != 0) ...

>If you implement Object::operator!=(int) then I think this should be used
>to perform your test.

I don't think if(a) is equivalent to if (a != 0). What the compiler
will do is attempt to convert a to a number. If you have an operator int()
that converts from Object to int, this int will be used for the test.
So, you want an operator int() in your Object class:

class Object {
    ...

public:
    ...
    operator int() const;
}

operator Object::int() const {
    return // 0 value for false, non-zero value for true
}

This is exactly how if(cin) works.
--
Steve Chapel        schapel@cs.ucsb.edu    |    http://www.cs.ucsb.edu/~schapel
University of California, Santa Barbara    |    finger -l schapel@eci1.ucsb.edu





Author: aishdas@haven.ios.com (Micha Berger)
Date: 1995/06/16
Raw View
wslade@atlanta.com wrote:
: However there are many times when I would like to
: test the opposite and find that the following code
: is clumsy:

: {
:   Object a;

:   if (!(!a))
:    return;
:   // Do something
: }

This is exactly why the "bool" type was introduced. define an
Object::operator bool(). This would be automatically invoked in an
if statement like
 if (a)
     return;

--
Micha Berger 201 916-0287        Help free Ron Arad, held by Syria 3153 days!
aishdas@haven.ios.com                     (16-Oct-86 - 16-Jun-95)
<a href=news:alt.religion.aishdas>Orthodox Judaism: Torah, Worship, Kindness</a>
<a href=http://haven.ios.com/~aishdas>AishDas Society's Home Page</a>





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/06/17
Raw View
schapel@zonker.cs.ucsb.edu (Steve E. Chapel) writes:

>I don't think if(a) is equivalent to if (a != 0).

Yes it is. That's the definition of "if(a)".

>What the compiler
>will do is attempt to convert a to a number.

No, it will convert 'a' to a type which can be compared against
zero. Any scalar type will do. A scalar is any integer, floating-
point, enum, or pointer type, and now type bool as well.

>If you have an operator int()
>that converts from Object to int, this int will be used for the test.

Yes, and the result is compared against zero. But conversion to
any other scalar type will work as well.

>So, you want an operator int() in your Object class:
>    ...
>This is exactly how if(cin) works.

No, current implementations usually have an "operator void*", not
"operator int".  You usually do not want a conversion to int,
since it leads to many more opportunities for ambiguous
and unintended conversions.

--
Steve Clamage, stephen.clamage@eng.sun.com





Author: wslade@atlanta.com
Date: 1995/06/16
Raw View
I often have a requirement to test whether an object is
valid or not. {Valid based on some attribute or logic
within the object}.

Hence I provide an operator!, which I use as follows

{
   Object a;

   if (!a)
     return;
   // Do something
}


However there are many times when I would like to
test the opposite and find that the following code
is clumsy:

{
  Object a;

  if (!(!a))
   return;
  // Do something
}

What I would really like to do is the following:

{
  Object a;
  if (a)
    return;
  // Do something
}

Any ideas or suggestions much appreciated.
----------------------------------------------------------------------
Warwick Slade                             | wslade@atlanta.com
Software Consultant                       | (wk) +1-404-671-8276
Computer Consulting Services Corporation  |
----------------------------------------------------------------------
Plus Tax, Plus Tax, Plus Tax, Plus Tax, Plus Tax, Plus Tax, Plus Tax.
----------------------------------------------------------------------