[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Opposite of ! operator.

jason.cipriani@gmail.com

11/22/2008 6:16:00 AM

If I have:

class Something {
public:
bool operator ! () const;
};

Then I can do:

Something s(...);
if (!s) ...;

My question is, what operator do I need to overload if I want to be
able to define the behavior of this instead:

Something s(...);
if (s) ...; // <-- notice no !

Sorry if the post title was stupid, I couldn't think of a better one.

Thanks,
Jason
18 Answers

Wang Yongxin

11/22/2008 6:29:00 AM

0

jason.cipriani@gmail.com wrote:
> If I have:
>
> class Something {
> public:
> bool operator ! () const;
> };
>
> Then I can do:
>
> Something s(...);
> if (!s) ...;
>
> My question is, what operator do I need to overload if I want to be
> able to define the behavior of this instead:
>
> Something s(...);
> if (s) ...; // <-- notice no !
>
> Sorry if the post title was stupid, I couldn't think of a better one.
>
> Thanks,
> Jason

Maybe you want to overload operator bool().

Paavo Helde

11/22/2008 7:27:00 AM

0

"jason.cipriani@gmail.com" <jason.cipriani@gmail.com> kirjutas:

> If I have:
>
> class Something {
> public:
> bool operator ! () const;
> };
>
> Then I can do:
>
> Something s(...);
> if (!s) ...;
>
> My question is, what operator do I need to overload if I want to be
> able to define the behavior of this instead:
>
> Something s(...);
> if (s) ...; // <-- notice no !


The common approach is to use

operator const void* () const;

Now you can write:

if (s) ...
if (!s) ...

This should return NULL for 'false' and a non-NULL valid pointer (like
'this') for 'true'. The problem with returning a bool is that it converts
to numeric types too easily and can create hidden errors. Yes, this seems
like a hack, but it's a widely used one.

hth
Paavo


Alan Johnson

11/22/2008 7:39:00 AM

0

jason.cipriani@gmail.com wrote:
> If I have:
>
> class Something {
> public:
> bool operator ! () const;
> };
>
> Then I can do:
>
> Something s(...);
> if (!s) ...;
>
> My question is, what operator do I need to overload if I want to be
> able to define the behavior of this instead:
>
> Something s(...);
> if (s) ...; // <-- notice no !
>
> Sorry if the post title was stupid, I couldn't think of a better one.
>
> Thanks,
> Jason

As others have mentioned the straightforward approach is to implement
operator bool or operator void *. Each of these has some type
conversion drawbacks that aren't immediately obvious. Safe solutions
exist but it gets complicated quickly. See:
http://www.artima.com/cppsource/saf...

--
Alan

Paavo Helde

11/22/2008 8:59:00 AM

0

Alan Johnson <awjcs@yahoo.com> kirjutas:

> jason.cipriani@gmail.com wrote:
>> If I have:
>>
>> class Something {
>> public:
>> bool operator ! () const;
>> };
>>
>> Then I can do:
>>
>> Something s(...);
>> if (!s) ...;
>>
>> My question is, what operator do I need to overload if I want to be
>> able to define the behavior of this instead:
>>
>> Something s(...);
>> if (s) ...; // <-- notice no !
>>
>> Sorry if the post title was stupid, I couldn't think of a better one.
>>
>> Thanks,
>> Jason
>
> As others have mentioned the straightforward approach is to implement
> operator bool or operator void *. Each of these has some type
> conversion drawbacks that aren't immediately obvious. Safe solutions
> exist but it gets complicated quickly. See:
> http://www.artima.com/cppsource/saf...

I scimmed the page, it seems the only objection to operator void* raised
there is that one can do:

Something s;
delete s;

However, one can do such silly things anyway:

Something s;
Something* p = &s;
delete p;

And more importantly, I believe that folks think twice before writing
'delete something', making sure they have the ownership of the object in
the first place and that the object has been indeed dynamically
allocated. Well, at least I hope so! Besides, when I compile 'delete s',
then I get a quite strong warning:

>g++ -Wall test2.cpp
test2.cpp: In function `int main()':
test2.cpp:8: warning: deleting `const void*' is undefined

Paavo



Erik Wikström

11/22/2008 9:00:00 AM

0

On 2008-11-22 08:26, Paavo Helde wrote:
> "jason.cipriani@gmail.com" <jason.cipriani@gmail.com> kirjutas:
>
>> If I have:
>>
>> class Something {
>> public:
>> bool operator ! () const;
>> };
>>
>> Then I can do:
>>
>> Something s(...);
>> if (!s) ...;
>>
>> My question is, what operator do I need to overload if I want to be
>> able to define the behavior of this instead:
>>
>> Something s(...);
>> if (s) ...; // <-- notice no !
>
>
> The common approach is to use
>
> operator const void* () const;
>
> Now you can write:
>
> if (s) ...
> if (!s) ...
>
> This should return NULL for 'false' and a non-NULL valid pointer (like
> 'this') for 'true'. The problem with returning a bool is that it converts
> to numeric types too easily and can create hidden errors. Yes, this seems
> like a hack, but it's a widely used one.

I'm wondering if the new explicit conversion functions will solve this.
The standard says:

A conversion function may be explicit, in which case it is only
considered as a user-defined conversion for direct-initialization.

Since there is no initialisation going on in "if (s)", I suppose that we
will still have to use the "operator void*" hack.

--
Erik Wikström

James Kanze

11/22/2008 11:16:00 AM

0

On Nov 22, 9:58 am, Paavo Helde <pa...@nospam.please.org> wrote:
> Alan Johnson <aw...@yahoo.com> kirjutas:
> > jason.cipri...@gmail.com wrote:
> >> If I have:

> >> class Something {
> >> public:
> >>   bool operator ! () const;
> >> };

> >> Then I can do:

> >> Something s(...);
> >> if (!s) ...;

> >> My question is, what operator do I need to overload if I want to be
> >> able to define the behavior of this instead:

> >> Something s(...);
> >> if (s) ...;  // <-- notice no !

> > As others have mentioned the straightforward approach is to implement
> > operator bool or operator void *.  Each of these has some type
> > conversion drawbacks that aren't immediately obvious.  Safe solutions
> > exist but it gets complicated quickly.  See:
> >http://www.artima.com/cppsource/saf...

> I scimmed the page, it seems the only objection to operator
> void* raised there is that one can do:

> Something s;
> delete s;

Not only. For historical reasons, void*'s show up a lot more
than one would like. Although not as dangerous as bool
(although in many cases, even bool isn't that dangerous---it's
major danger in the case of iostream is due to the fact that
iostream overloads << and >>), if you really want safety, it's
not too difficult to return a pointer to a member of a private
class; there's practically nothing a client can do with it
except convert it to bool. This route may be worth going if
you're developing a library which will be used everywhere, and
must be ultra-robust. Otherwise, I'd just go with the operator
bool, unless the class overrides operators which would be valid
on an integral type.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Pete Becker

11/22/2008 11:39:00 AM

0

On 2008-11-22 04:00:25 -0500, Erik Wikström <Erik-wikstrom@telia.com> said:

>
> I'm wondering if the new explicit conversion functions will solve this.
> The standard says:
>
> A conversion function may be explicit, in which case it is only
> considered as a user-defined conversion for direct-initialization.
>
> Since there is no initialisation going on in "if (s)", I suppose that we
> will still have to use the "operator void*" hack.

That would be silly. Take a look at [conv]/4, which defines the term
"contextually converted". Expressions used as conditions are
contextually converted to bool, as if by direct initialization.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Gennaro Prota

11/22/2008 1:39:00 PM

0

Pete Becker wrote:
> On 2008-11-22 04:00:25 -0500, Erik Wikström <Erik-wikstrom@telia.com> said:
>
>>
>> I'm wondering if the new explicit conversion functions will solve this.
>> The standard says:
>>
>> A conversion function may be explicit, in which case it is only
>> considered as a user-defined conversion for direct-initialization.
>>
>> Since there is no initialisation going on in "if (s)", I suppose that we
>> will still have to use the "operator void*" hack.
>
> That would be silly. Take a look at [conv]/4, which defines the term
> "contextually converted". Expressions used as conditions are
> contextually converted to bool, as if by direct initialization.

Phew :-) This wasn't in the proposed 'Changes to the Standard'
of n1592. I emailed the author about it but never got a reply.

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/b...
Do you need expertise in C++? I'm available.

Gennaro Prota

11/22/2008 1:51:00 PM

0

Alan Johnson wrote:
> jason.cipriani@gmail.com wrote:
>> If I have:
>>
>> class Something {
>> public:
>> bool operator ! () const;
>> };
>>
>> Then I can do:
>>
>> Something s(...);
>> if (!s) ...;
>>
>> My question is, what operator do I need to overload if I want to be
>> able to define the behavior of this instead:
>>
>> Something s(...);
>> if (s) ...; // <-- notice no !
>>
>> Sorry if the post title was stupid, I couldn't think of a better one.
>>
>> Thanks,
>> Jason
>
> As others have mentioned the straightforward approach is to implement
> operator bool or operator void *. Each of these has some type
> conversion drawbacks that aren't immediately obvious. Safe solutions
> exist but it gets complicated quickly. See:
> http://www.artima.com/cppsource/saf...

And there's more, for instance to protect against unintended ADL
when you put everything in a reusable base class.

A simpler approach (more an experiment than anything else)
is:

<http://breeze.svn.sourceforge.net/viewvc/breeze/trunk/breeze/idiom/bool_testable.hpp?vi...

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/b...
Do you need expertise in C++? I'm available.

Daniel T.

11/22/2008 2:59:00 PM

0

On Nov 22, 1:15 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
> If I have:
>
> class Something {
> public:
>   bool operator ! () const;
>
> };
>
> Then I can do:
>
> Something s(...);
> if (!s) ...;
>
> My question is, what operator do I need to overload if I want to be
> able to define the behavior of this instead:
>
> Something s(...);
> if (s) ...;  // <-- notice no !
>
> Sorry if the post title was stupid, I couldn't think of a better one.

The best solution is to have a named member-function that explains
what the result stands for.

class Something {
public:
bool isOpen() const;
bool isValid() const;
bool isFoo() const;
};

Something s;
if (s.isOpen()) ...;