What is boost's unspecified_bool_type?

D

dru

Every time I think I know or understand C++ with some
confidence, I see something that changes that.

I was looking at the boost shared_ptr docs and code, and
I ran across the operator unspecified_bool_type()

In the code they have this:


#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)

operator bool () const
{
return px != 0;
}

#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__,
BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;

operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::get;
}

#else

typedef T * this_type::*unspecified_bool_type;

operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::px;
}

#endif

// operator! is redundant, but some compilers need it

bool operator! () const // never throws
{
return px == 0;
}


Here are some things to note.

1. That SunCC implementation is very easy to understand, and is often
used in MSVC as well.

2. The MWERKS workaround is fairly weird. Skip it.

3. The third section is the real code. What is the operator really of
with that typdef that I cannot parse???

4. I included the operator ! just for fun. That implementation appears
to be
straigthfowrard for all implementations. It's simplicity is probably a
clue why the other ones are not; some asymetry in the C++ semantics.

*Please post replies here, thx*
 
J

John Harrison

dru said:
Every time I think I know or understand C++ with some
confidence, I see something that changes that.

I know that feeling.
I was looking at the boost shared_ptr docs and code, and
I ran across the operator unspecified_bool_type()

In the code they have this:


#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)

operator bool () const
{
return px != 0;
}

#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__,
BOOST_TESTED_AT(0x3003))
typedef T * (this_type::*unspecified_bool_type)() const;

operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::get;
}

#else

typedef T * this_type::*unspecified_bool_type;

operator unspecified_bool_type() const // never throws
{
return px == 0? 0: &this_type::px;
}

#endif

// operator! is redundant, but some compilers need it

bool operator! () const // never throws
{
return px == 0;
}


Here are some things to note.

1. That SunCC implementation is very easy to understand, and is often
used in MSVC as well.

2. The MWERKS workaround is fairly weird. Skip it.

3. The third section is the real code. What is the operator really of
with that typdef that I cannot parse???

4. I included the operator ! just for fun. That implementation appears
to be
straigthfowrard for all implementations. It's simplicity is probably a
clue why the other ones are not; some asymetry in the C++ semantics.

*Please post replies here, thx*

The unspecified_bool_type is a pointer to a member function. The problem
with the SunCC implementation is that operator bool could be used in places
you don't want. For instance with operator bool

shared_ptr<X> xp;
float f = xp;

becomes legal code (implicit call of operator bool, followed by promotion of
bool to float).

Pointers to member functions are used instead because they are much less
likely to be result in unintended conversions to other types, but are still
usable in situations where a Boolean value is needed

shared_ptr<X> xp;
if (xp) // implicit conversion to unspecified_bool_type, followed by
check for NULL
{
}

operator void* is also sometimes used for similar reasons, but operator
unspecified_bool_type is better I think.

john
 
D

dru

First, thanks for your reply.
The unspecified_bool_type is a pointer to a member function. The problem
with the SunCC implementation is that operator bool could be used in places
you don't want. For instance with operator bool

shared_ptr<X> xp;
float f = xp;

becomes legal code (implicit call of operator bool, followed by promotion of
bool to float).

I can see that, but I don't see a major threat there.

Pointers to member functions are used instead because they are much less
likely to be result in unintended conversions to other types, but are still
usable in situations where a Boolean value is needed

shared_ptr<X> xp;
if (xp) // implicit conversion to unspecified_bool_type, followed by
check for NULL
{
}

operator void* is also sometimes used for similar reasons, but operator
unspecified_bool_type is better I think.

Where can I find in the ARM the description of a conversion from a pointer
to a bool?


On a side note, I wish you could do the following with a shared pointer.

xyz = NULL;

It would be nice, but I understand the reasons for it's absence.
 
J

John Harrison

dru said:
First, thanks for your reply.


I can see that, but I don't see a major threat there.

Not sure I agree with that. Unexpected converion to a numeric type can be
very confusing, usually easily fixed when spotted though.

[snip]
Where can I find in the ARM the description of a conversion from a pointer
to a bool?

Sorry I'm not familar with ARM. In the C++ standard it's section 4.12. All
it says is that any pointer or pointer to member can be converted to a bool
rvalue, and that null pointers convert to false and other values to true.

john
 
J

Jeff Flinn

dru,

dru said:
First, thanks for your reply.
[spip]

On a side note, I wish you could do the following with a shared pointer.

xyz = NULL;

It would be nice, but I understand the reasons for it's absence.

how about:

xyz.reset();

Jeff F
 
D

dru

On a side note, I wish you could do the following with a shared pointer.
how about:

xyz.reset();

Yep, know all about that. I would prefer = NULL to be like the
ole' MS style or .clear() to be like the STL folk.

dru
 
H

Howard Hinnant

On a side note, I wish you could do the following with a shared pointer.

xyz = NULL;

It would be nice, but I understand the reasons for it's absence.

Actually I think that's a very good suggestion. I think it can be done
safely. We need a non-explicit shared_ptr constructor taking a pointer
to a private type (such as unspecified_bool_type). Hmm... I need to
give that a little more thought, but it looks promising to me.

-Howard
 
R

Richard Herring

dru said:
Yep, know all about that. I would prefer = NULL to be like the
ole' MS style or .clear()

But xyz.reset() is just the defaulted-argument special case of
xyz.reset(pointer-to-something). Either you give it a name that's
inappropriate for the more general case, or you have a proliferation of
member functions with overlapping effects.
to be like the STL folk.

who can't even decide whether a string has a .length() or a .size() ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top