473,377 Members | 1,119 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,377 software developers and data experts.

Allowing a class to be converted to bool?

Is it possible to allow a class to be converted to bool?

For example, if I have:
class foo {
private:
unsigned i;
};

and I want to evaluate:
if (foo)
by looking at foo.i, how can I do that?

Thanks

Joseph

Dec 29 '05 #1
10 1675
Joseph Turian wrote:
Is it possible to allow a class to be converted to bool?

For example, if I have:
class foo {
private:
unsigned i;
};

and I want to evaluate:
if (foo)
by looking at foo.i, how can I do that?


Use a conversion operator ...

class foo
{
public:
operator bool()
{
return i != 0;
}
.....
Dec 29 '05 #2
Joseph Turian wrote:
Is it possible to allow a class to be converted to bool?

For example, if I have:
class foo {
private:
unsigned i;
};

and I want to evaluate:
if (foo)
by looking at foo.i, how can I do that?


class foo
{
public:
operator bool() const
{
return i != 0;
}

private:
unsigned i;
};

But know that this makes it possible for your class to be converted:

foo f;

if (f) ; // cool
int a = f; // .. also works
Jonathan

Dec 29 '05 #3

Jonathan Mcdougall wrote:
But know that this makes it possible for your class to be converted:

foo f;
if (f) ; // cool
int a = f; // .. also works


Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.

i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.

Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?
Thanks!

Joseph

Dec 29 '05 #4
Joseph Turian wrote:
Jonathan Mcdougall wrote:
But know that this makes it possible for your class to be converted:

foo f;
if (f) ; // cool
int a = f; // .. also works


Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.

i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.

Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?


Yes. Implicitly converting to a bool would open the door to type
conversions that you probably would not want.

In this case, you can lift a page from boost shared_ptr and return a
dummy member function pointer. Member function pointers are
sufficiently restricted that a program cannot do much with one beyond
testing it for NULL.

class foo
{
private:
unsigned i;

typedef unsigned foo::*unspecified_bool_type;

public:
foo() : i(0) {}

operator unspecified_bool_type() const
{
return i ? &foo::i : NULL;
}
};

Now:

foo f;

if (f) {} // OK
int a = f; // Error

Greg

Dec 29 '05 #5
If you have 3 classes A, B and C which contain unsigned int member.
These cant be compared with each other unless you provide a conversion
operator to a common type (say unsigned int or bool) in each of these
classes or you overload assignment operator in these classes to allow
such comparison.
If you provide a conversion operator say "operator unsigned int()" in
all 3 classes then when you do if(A==B), this conversion function is
called which converts the operands to unsigned int and then compare
these. When you derive A, B and C from another class foo which provides
another conversion operator "operator bool()", then (A==B) will become
ambiguous as there are two possible conversions before comparison. So
this will disallow the comparisons the way you like.
Regarding type-conversion risk, as mentioned by Jonathan, conversion
operator is invoked whenver you use the class object in boolean context
and wont be restricted only to comparisons.

Dec 29 '05 #6
Joseph Turian wrote:
Jonathan Mcdougall wrote:
But know that this makes it possible for your class to be converted:

foo f;
if (f) ; // cool
int a = f; // .. also works
Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.


Good thing.
i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.
"So"? If you want A, B and C yo be considered distinct types, don't
derive them from a base class!
Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
No, it has no influence. A, B and C cannot be compared or converted
between themselves if you did not write the correct operators. They can
be converted to foo's though.
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?


Of course, as do all conversion operators. Consider this:

# include <complex>

class C
{
public:
C(double d);
};

class foo
{
public:
operator bool();
};

int main()
{
foo f;

C c(f); // hmmm
if (f == 'A') ; // oups
std::complex<int> s(f); // what?
}

You could use an operator void* instead:

class foo()
{
public:
operator void*()
{
return i ? &i : 0;
}

private:
int i;
};

If you're careful, that conversion may not be dangerous.

For maximum safety, consider using a named member function. Sometimes,
safety is more important than convenience.
Jonathan

Dec 29 '05 #7
anujanujdham...@gmail.com wrote:
Regarding type-conversion risk, as mentioned by Jonathan, conversion
operator is invoked whenver you use the class object in boolean context
and wont be restricted only to comparisons.


Actually, it would be more accurate to say that this conversion
operator is considered when an integral type is expected.
Jonathan

Dec 29 '05 #8

Greg wrote:
Joseph Turian wrote:
Jonathan Mcdougall wrote:
But know that this makes it possible for your class to be converted:

foo f;
if (f) ; // cool
int a = f; // .. also works


Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.

i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.

Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?


Yes. Implicitly converting to a bool would open the door to type
conversions that you probably would not want.

In this case, you can lift a page from boost shared_ptr and return a
dummy member function pointer. Member function pointers are
sufficiently restricted that a program cannot do much with one beyond
testing it for NULL.

class foo
{
private:
unsigned i;

typedef unsigned foo::*unspecified_bool_type;

public:
foo() : i(0) {}

operator unspecified_bool_type() const
{
return i ? &foo::i : NULL;
}
};

Now:

foo f;

if (f) {} // OK
int a = f; // Error

Greg

typedef unsigned foo::*unspecified_bool_type; --
what is ti mean?

Dec 29 '05 #9

Joseph Turian skrev:
Jonathan Mcdougall wrote:
But know that this makes it possible for your class to be converted:

foo f;
if (f) ; // cool
int a = f; // .. also works
Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.

i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.


There is no need to inherit - as Jonathan told you.

An elegant way to allow many such similar classes and have them be
distinct would be to use a template:

template<int id> class personalized_int
{
...
};
The only purpose of the template would be to faciliate the easy
creation of new types - so inside the class template, everything will
look as if the class was nontemplated.

When you're done you can use a typedef to get to a "userfriendly" name:

typedef personalized_int<0> apple_t;
typedef personalized_int<1> orange_t;
orange_t oranges = 10;
apple_t apples = 30;

if (apples < oranges) // causes compile-error
/Peter
Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?
Thanks!

Joseph


Dec 29 '05 #10
puzzlecracker wrote:
Greg wrote:
Joseph Turian wrote:
Jonathan Mcdougall wrote:

> But know that this makes it possible for your class to be converted:
>
> foo f;
> if (f) ; // cool
> int a = f; // .. also works

Okay wait.

The whole reason I created a class 'foo' which wraps the POD type
'unsigned' is because I want to ensure type-safety by creating several
sub-types of foo.

i.e. I want to have three classes A, B, and C which are essentially of
type 'unsigned'.
However, I want A, B, and C to be considered distinct types and to
have, say, comparisons between A and B types to cause a compiler error.
So, to do so, I want to have A, B, and C inherit from foo.

Question 1: Does having A, B, and C inherit from foo achieve the
desired effect of disallowing comparisons and casts between types A, B,
and C?
Question 2: Does adding the operator bool conversion function open me
to any type-conversion risks?


Yes. Implicitly converting to a bool would open the door to type
conversions that you probably would not want.

In this case, you can lift a page from boost shared_ptr and return a
dummy member function pointer. Member function pointers are
sufficiently restricted that a program cannot do much with one beyond
testing it for NULL.

class foo
{
private:
unsigned i;

typedef unsigned foo::*unspecified_bool_type;

public:
foo() : i(0) {}

operator unspecified_bool_type() const
{
return i ? &foo::i : NULL;
}
};

Now:

foo f;

if (f) {} // OK
int a = f; // Error

Greg

typedef unsigned foo::*unspecified_bool_type; --
what is ti mean?


It's a typedef declaration that makes the name "unspecified_bool_type"
an alias for a data member pointer to an unsigned int data member of
foo. The subsequent unspecified_bool_type conversion operator returns
such a data member pointer when i is not 0 or NULL otherwise.

Greg

Dec 29 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Oplec | last post by:
Hi, I'm learning C++ as a hobby using The C++ Programming Language : Special Edition by Bjarne Stroustrup. I'm working on chpater 13 exercises that deal with templates. Exercise 13.9 asks for me...
3
by: Pierre Espenan | last post by:
A have a long integer class. The built integer type within a conditional statement returns bool false for int i=0 and bool true for any other non zero value. I want my long integer class to have...
5
by: Peter Meier | last post by:
Hello everybody, Stroustrup says he prefer's to declare operators, which do not do anything on the class itself global. Does anybody know the reason for that? Any advantages/disadvantages? ...
1
by: Stephane Vollet | last post by:
Hi everyone, I am trying to Print (display) all the items of a vector (class TvectorStat) which is into another class (class Tpile). Apparently I can't reach m_size of Class TvectorStat because...
11
by: James Aguilar | last post by:
In the C++ STL, there are various places where you can call a function that takes a functor as a parameter. This functor may be either a function object or a function pointer. For instance, if...
3
by: Chris | last post by:
I am having a very strange problem involving virtual functions in template classes. First of all, here is an extremely simplified structure of the two classes I am having problems with. ...
21
by: phpCodeHead | last post by:
Code which should allow my constructor to accept arguments: <?php class Person { function __construct($name) { $this->name = $name; } function getName()
20
by: tshad | last post by:
Using VS 2003, I am trying to take a class that I created to create new variable types to handle nulls and track changes to standard variable types. This is for use with database variables. This...
2
by: =?ISO-8859-1?Q?Andr=E9_Luiz_Carvalho?= | last post by:
Hi there, I'm porting an application from Java to C++ / BREW so I can't use the stl, therefore, I have to implement the basic structures that the app use in Java. I'm implementing a Hashtable...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.