overloading for specific implicit casts

S

Simon Ford

Hi All,

I'm having trouble understanding exactly how I can do some specific implicit
casting. There are two problems here; does anyone know what I should be
doing?

//----------
// (1) Resolving as bool for comparison, but not as int.
//
// we have a class

class Foo{};
Foo x;

// I want to allow for a test of class Foo (i.e. returning bool)

if(x) {}

// which is probably done using : operator bool() const
// However, I don't want the compiler to allow this implicit cast
// to go through bool to int:

int y = 5;
int z = x + y; // should be an error

// i.e. z should not become 6, it should throw a compile error
// How do I allow the implicit boolean conversion without allowing
// the further integer conversion?
//----------
// (2) Casting from another type
//
// we have some operators overloaded:

bool operator== (Foo& lhs, Foo& rhs);

// Now, I would like to allow an implicit cast from another chosen type
// (string) to allow a comparison:

if(x == "bar") {} // "bar" is implicitly cast to a Foo of flavour bar

// i.e. avoiding having to define the two other variants for every operator

bool operator== (string lhs, Foo& rhs); // don't want to define this!
bool operator== (Foo& lhs, string rhs); // don't want to define this!

// How would I go about doing this?
//----------

Thanks for your time,
Simon ;o)
 
T

tom_usenet

Hi All,

I'm having trouble understanding exactly how I can do some specific implicit
casting. There are two problems here; does anyone know what I should be
doing?

//----------
// (1) Resolving as bool for comparison, but not as int.
//
// we have a class

class Foo{};
Foo x;

// I want to allow for a test of class Foo (i.e. returning bool)

if(x) {}

// which is probably done using : operator bool() const
// However, I don't want the compiler to allow this implicit cast
// to go through bool to int:

int y = 5;
int z = x + y; // should be an error

// i.e. z should not become 6, it should throw a compile error
// How do I allow the implicit boolean conversion without allowing
// the further integer conversion?

The usual technique is to implement operator void* rather than
operator bool. void* can't take part in pointer arithmetic, can't be
assigned to any other built in types, but does convert conveniently to
a bool. e.g. something like this:

operator void const*() const
{
if(I'm true)
return this;//must return a valid non-null address; "this" will do
else
return 0;
}

The iostreams heirarchy uses this trick.
//----------
// (2) Casting from another type
//
// we have some operators overloaded:

bool operator== (Foo& lhs, Foo& rhs);

// Now, I would like to allow an implicit cast from another chosen type
// (string) to allow a comparison:

if(x == "bar") {} // "bar" is implicitly cast to a Foo of flavour bar

// i.e. avoiding having to define the two other variants for every operator

bool operator== (string lhs, Foo& rhs); // don't want to define this!
bool operator== (Foo& lhs, string rhs); // don't want to define this!

// How would I go about doing this?

Provide a Foo constructor that takes a string. e.g.

Foo(std::string const& s);
or possibly
Foo(std::string s);

Tom
 
D

David B. Held

tom_usenet said:
[...]
The usual technique is to implement operator void* rather
than operator bool. void* can't take part in pointer arithmetic,
can't be assigned to any other built in types, but does
convert conveniently to a bool. e.g. something like this:
[...]

Even better than that is the trick used in Loki::SmartPtr or
boost::shared_ptr. I'll show the Boost version here, because
it's shorter:

typedef T * (this_type::*unspecified_bool_type)() const;

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

The difference between this and void* is that the delete
expression is no longer legal, so the compiler is required
to diagnose it (as opposed to silently invoking undefined
behaviour).

Note that there is currently discussion that a pointer-to-
member might be even more desirable than a pointer-to-
member-function.

Loki makes a private class and makes the delete operator
private and returns a pointer to that class. That achieves
the same goal.

Dave
 
S

Simon Ford

Thanks for the response - half good news, half bad news...
The usual technique is to implement operator void* rather than
operator bool. void* can't take part in pointer arithmetic, can't be
assigned to any other built in types, but does convert conveniently to
a bool. e.g. something like this:

operator void const*() const
{
if(I'm true)
return this;//must return a valid non-null address; "this" will do
else
return 0;
}

This seemed to work, thanks.
Provide a Foo constructor that takes a string. e.g.

Foo(std::string const& s);
or possibly
Foo(std::string s);

I thought this should be enough too, but it complains there is no acceptable
conversion. Any other ideas?

Thanks again,
Simon.
 
T

tom_usenet

I thought this should be enough too, but it complains there is no acceptable
conversion. Any other ideas?

Your operator== signature is a non-member function like this, right?

bool operator==(Foo const& lhs, Foo const& rhs);

If you miss out the const, you can't pass temporaries to the method...

Tom
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top