From: James Kanze on
On Jul 31, 3:33 pm, sbi <non...(a)invalid.invalid> wrote:
> James Kanze wrote:
> > On Jul 13, 2:01 pm, sbi <non...(a)invalid.invalid> wrote:
> > [...]
> >> Am I missing something here or is it purely for (mistaken)
> >> historical reasons that std::basic_ios::operator!() is
> >> defined?

> > Probably for reasons of orthogonality. Any time you
> > overload operator bool() (and the operator void*() is
> > a disguised overload of operator bool()), you also overload
> > operator!(). It's just good coding practice.

> James, over the years I have learned to respect your
> knowledge, but "it's just good coding practice" isn't enough
> for me to be convinced by you.

Substitute "usual", or "expected", then, instead of "good".
Psychologically, it's done more or less for the same reason one
overloads != if one overloads ==.

> If this was true, there ought to be a reason that's possible
> to explain.

Today, yes. Everyone does it, and your code sticks out and
looks funny if it doesn't.

> Could you please cite that reason to back up this statements?
> Also, there's contrary evidence. For starters, if this was
> true, the standard library's smart pointers should follow that
> practice. Yet, they don't.

A smart pointer shouldn't convert to a pseudo-bool to begin
with. Just because you're emulating pointers, there's no reason
to emulate their misfeatures. (My smart pointers do support
comparaison with NULL. Both == and !=. For auto_ptr, the only
solution I've seen is ptr.get() == NULL.)

--
James Kanze

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: sbi on
James Kanze wrote:
> On Jul 31, 3:33 pm, sbi <non...(a)invalid.invalid> wrote:
>> James Kanze wrote:
>>> On Jul 13, 2:01 pm, sbi <non...(a)invalid.invalid> wrote:
>>> [...]
>>>> Am I missing something here or is it purely for (mistaken)
>>>> historical reasons that std::basic_ios::operator!() is
>>>> defined?
>
>>> Probably for reasons of orthogonality. Any time you
>>> overload operator bool() (and the operator void*() is
>>> a disguised overload of operator bool()), you also overload
>>> operator!(). It's just good coding practice.
>
>> James, over the years I have learned to respect your
>> knowledge, but "it's just good coding practice" isn't enough
>> for me to be convinced by you.
>
> Substitute "usual", or "expected", then, instead of "good".

If this was indeed so expected, my question would have caused a roar of
people jelling "because!" at me. Yet, I had to repeatedly ask to get even
three opinions on the matter, and not one of them came up with a convincing
reason.

> Psychologically, it's done more or less for the same reason one
> overloads != if one overloads ==.

But there's a difference: a==b cannot be implicitly used by the compiler
when a!=b is required. A !mystream, however, works with the implicit
conversion to a boolean-like type.

>> If this was true, there ought to be a reason that's possible
>> to explain.
>
> Today, yes. Everyone does it, and your code sticks out and
> looks funny if it doesn't.

Except for streams, I cannot remember a single time I have seen operator!
overloaded. I have, OTOH, seen many operator bool-lookalikes. If overloading
operator! was "usual" and "expected" for such types, you'd think I should
have come across it in more than 15 years of C++ coding.
I conclude that you're wrong there. _Nobody_ does it. And why should they?
You still haven't given a rationale. Negating objects works with just an
implicit boolean conversion in place, operator! isn't needed for that.

>> Could you please cite that reason to back up this statements?
>> Also, there's contrary evidence. For starters, if this was
>> true, the standard library's smart pointers should follow that
>> practice. Yet, they don't.
>
> A smart pointer shouldn't convert to a pseudo-bool to begin
> with. [tangent snipped]

Whether this is right or wrong is unimportant here. What's important,
though, is the fact that the designers of the standard library's smart
pointer classes, like me, seem to have never heard about the "usual" and
"expected" overloading of operator!.
Perhaps they, like me, didn't see a reason to do so?

sbi

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 13 Jul., 15:01, sbi <non...(a)invalid.invalid> wrote:
> Hallo,
>
> The C++ IO streams' base class std::basic_ios defines operator void*()
> to return a safe bool indicating !fail() and operator!() to return fail().
> That makes me wonder why we need the operator!() at all. Certainly, !is
> would also work by implicitly calling operator void*() and negating its
> result.
>
> Am I missing something here or is it purely for (mistaken) historical
> reasons that std::basic_ios::operator!() is defined?

I have been told, that this additional declaration was added to
emphasize
the symmetry between the "true" case and it's negation, just as a
guide
for the reader, nothing more. To be fair, the idiom

operator void*

was rather new at this time and given this the deduction which syntax
support is provided by this feature is not immediately obvious. Other
than that there was no further technical reason to do so.
Nevertheless
you might still find some buggy compilers that don't get the
conversion
right without the additional operator!. As far as I remember
correctly, I
needed to provide operator! additionally for old Borland compilers.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]