Connecting Tech Pros Worldwide Forums | Help | Site Map

overloading for specific implicit casts

Simon Ford
Guest
 
Posts: n/a
#1: Jul 19 '05
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)



tom_usenet
Guest
 
Posts: n/a
#2: Jul 19 '05

re: overloading for specific implicit casts


On Mon, 22 Sep 2003 11:19:53 +0100, "Simon Ford"
<simon_news@mookstar.co.uk> wrote:
[color=blue]
>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?[/color]

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.
[color=blue]
>//----------
>// (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?[/color]

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

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

Tom
David B. Held
Guest
 
Posts: n/a
#3: Jul 19 '05

re: overloading for specific implicit casts


"tom_usenet" <tom_usenet@hotmail.com> wrote in message
news:pqntmvcftfegivsc008ebl8ke15tjp3fgt@4ax.com...[color=blue]
> [...]
> 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:
> [...][/color]

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


Simon Ford
Guest
 
Posts: n/a
#4: Jul 19 '05

re: overloading for specific implicit casts


Thanks for the response - half good news, half bad news...
[color=blue][color=green]
> >// I want to allow for a test of class Foo (i.e. returning bool)
> >
> >if(x) {}[/color]
> 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;
> }[/color]

This seemed to work, thanks.
[color=blue][color=green]
> >//----------
> >// (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[/color][/color]
operator[color=blue][color=green]
> >
> >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?[/color]
>
> Provide a Foo constructor that takes a string. e.g.
>
> Foo(std::string const& s);
> or possibly
> Foo(std::string s);[/color]

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

Thanks again,
Simon.



tom_usenet
Guest
 
Posts: n/a
#5: Jul 19 '05

re: overloading for specific implicit casts


On Tue, 23 Sep 2003 15:57:24 +0100, "Simon Ford"
<simon_news@mookstar.co.uk> wrote:
[color=blue][color=green]
>> Provide a Foo constructor that takes a string. e.g.
>>
>> Foo(std::string const& s);
>> or possibly
>> Foo(std::string s);[/color]
>
>I thought this should be enough too, but it complains there is no acceptable
>conversion. Any other ideas?[/color]

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
Closed Thread


Similar C / C++ bytes