overloading for specific implicit casts | | |
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) | | | | 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 | | | | 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 | | | | 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. | | | | 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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|