C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

T::operator int () const ambiguous with T::operator Handle (
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Tim Clacy
Guest





PostPosted: Fri Apr 29, 2005 4:45 pm    Post subject: T::operator int () const ambiguous with T::operator Handle ( Reply with quote



Please illuminate; what operator of class 'Event' will get matched for these
two cases [see Event outline later]:

Event ev1;
Event ev2;

// Case 1
//
if (ev1)
;

// Case 2
//
if (ev1 || ev2)
;

I would have thought 'operator int ()' is the only obvious match, but my
compiler generates errors:

"ambiguous 3-way choice of conversion from 'struct Event' in Boolean
context

All I'm trying to do is wrap an OS event in a class that can be treated like
a Boolean; can anyone explain what the ambiguity is and how it can be
resolved (preferable without casts)?

Best regards


Tim





typedef struct tagHandle { }* Handle;

bool eventIsSignalled(Handle hEvent);

struct Event
{
:
bool IsSignalled() const { return eventIsSignalled(*this); }

operator int () const { return IsSignalled(); }
operator Handle () const { return handle; }

private:
Handle handle;
};


Back to top
Shezan Baig
Guest





PostPosted: Fri Apr 29, 2005 4:59 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote




Tim Clacy wrote:
Quote:
typedef struct tagHandle { }* Handle;

bool eventIsSignalled(Handle hEvent);

struct Event
{
:
bool IsSignalled() const { return eventIsSignalled(*this); }

operator int () const { return IsSignalled(); }
operator Handle () const { return handle; }



ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.



Quote:

private:
Handle handle;
};


Back to top
abecedarian@spambob.com
Guest





PostPosted: Fri Apr 29, 2005 8:28 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote



Shezan Baig wrote:
Quote:
Tim Clacy wrote:
typedef struct tagHandle { }* Handle;

try instead:
struct Handle { SomeType* realHandle; };

Quote:
bool eventIsSignalled(Handle hEvent);

struct Event
{
:
bool IsSignalled() const { return eventIsSignalled(*this); }

operator int () const { return IsSignalled(); }
operator Handle () const { return handle; }

ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.


Back to top
ben
Guest





PostPosted: Sat Apr 30, 2005 7:18 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote


Quote:
All I'm trying to do is wrap an OS event in a class that can be treated
like
a Boolean; can anyone explain what the ambiguity is and how it can be
resolved (preferable without casts)?
...
typedef struct tagHandle { }* Handle;

bool eventIsSignalled(Handle hEvent);

struct Event
{
:
bool IsSignalled() const { return eventIsSignalled(*this); }

operator int () const { return IsSignalled(); }
operator Handle () const { return handle; }

private:
Handle handle;
};


If Event::IsSignalled does fine, why use operator int?
Event itself is not a handle, why provide Handle operator?

To simplify:

struct Event
{
private:
Handle handle;

public:
Handle GetHandle() const
{
return handle;
}

operator int() const
{
return eventIsSignalled();
}

//...
};



Back to top
Tim
Guest





PostPosted: Sat Apr 30, 2005 1:55 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote


<abecedarian (AT) spambob (DOT) com> wrote

Quote:
Shezan Baig wrote:
Tim Clacy wrote:
typedef struct tagHandle { }* Handle;

try instead:
struct Handle { SomeType* realHandle; };

Shezen,

Hi. I can't try right now but how would that help?

Quote:
ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.

Hmm, that means that no C++ class can be used in an 'if' statement if it has
more than one operator that returns a POD type... doesn't it?



Back to top
Tim
Guest





PostPosted: Sat Apr 30, 2005 2:04 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote


"ben" <benhongh (AT) hotmail (DOT) com> wrote

Quote:

All I'm trying to do is wrap an OS event in a class that can be treated
like
a Boolean; can anyone explain what the ambiguity is and how it can be
resolved (preferable without casts)?
...
typedef struct tagHandle { }* Handle;

bool eventIsSignalled(Handle hEvent);

struct Event
{
:
bool IsSignalled() const { return eventIsSignalled(*this); }

operator int () const { return IsSignalled(); }
operator Handle () const { return handle; }

private:
Handle handle;
};


If Event::IsSignalled does fine, why use operator int?
Event itself is not a handle, why provide Handle operator?

To simplify:

struct Event
{
private:
Handle handle;

public:
Handle GetHandle() const
{
return handle;
}

operator int() const
{
return eventIsSignalled();
}

//...
};

Ben,

Hi. It looks like I'll have to run with your suggestion. 'operator int'; is
convenient in 'if' and || expressions for exactly the same reason that you
would prefer this:

if (a || b || c)
;

to this:

if ((a != false) || (b != false) || (c != false))
;

I'm a little disappointed that 'operator in' isn't a better match that
'operator void*' in an 'if' expression. This is surely a case of 'C'
crippling the power of C++ operator overloading isn't it?

Regards


Tim



Back to top
Julián Albo
Guest





PostPosted: Sat Apr 30, 2005 2:07 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Tim wrote:

Quote:
ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.
Hmm, that means that no C++ class can be used in an 'if' statement if it
has more than one operator that returns a POD type... doesn't it?

Just define a conversion to bool for that class.

--
Salu2

Back to top
Pete Becker
Guest





PostPosted: Sat Apr 30, 2005 2:27 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Tim wrote:
Quote:

Hmm, that means that no C++ class can be used in an 'if' statement if it has
more than one operator that returns a POD type... doesn't it?


No. POD types aren't inherently convertible to bool. Some of them (in
particular, builtin types) are.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Back to top
Ian
Guest





PostPosted: Sun May 01, 2005 3:01 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Julián Albo wrote:
Quote:
Tim wrote:


ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.

Hmm, that means that no C++ class can be used in an 'if' statement if it
has more than one operator that returns a POD type... doesn't it?


Just define a conversion to bool for that class.

And then live with all the bizarre run time errors such an operator will

give you!

Use a bool member like isOK(), the extra typing is worth it.

Ian

Back to top
Julián Albo
Guest





PostPosted: Sun May 01, 2005 4:25 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Ian wrote:

Quote:
Julián Albo wrote:
Tim wrote:


ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.

Hmm, that means that no C++ class can be used in an 'if' statement if it
has more than one operator that returns a POD type... doesn't it?
Just define a conversion to bool for that class.
And then live with all the bizarre run time errors such an operator will
give you!
Use a bool member like isOK(), the extra typing is worth it.

I do. But the question was if that can be done.

--
Salu2

Back to top
Tim
Guest





PostPosted: Mon May 02, 2005 6:46 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

"Julián Albo" <JULIANALBO (AT) terra (DOT) es> wrote

Quote:
Tim wrote:

ints *and* pointers are convertible to boolean (with the same
priority). So it is ambigious.
Hmm, that means that no C++ class can be used in an 'if' statement if it
has more than one operator that returns a POD type... doesn't it?

Just define a conversion to bool for that class.

--
Salu2

Julián,

Hi. Are you saying that 'operator bool' would be matched in preference to
'operator int' for an 'if' expression?



Back to top
Julián Albo
Guest





PostPosted: Mon May 02, 2005 3:00 pm    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Tim wrote:

Quote:
Hi. Are you saying that 'operator bool' would be matched in preference to
'operator int' for an 'if' expression?

Don't checked the standard but gcc accepts it:


// boolconv.cpp

#include <iostream>

class Convertible {
public:
operator int () { return 0; }
operator long () { return 0; }
operator unsigned int () { return 0; }
operator unsigned long () { return 0; }
operator bool () { return true; }
};

int main ()
{
Convertible c;
if (c)
std::cout << "Hello, world" << std::endl;
}

$ g++ -Wall -pedantic -std=c++98 -o boolconv boolconv.cpp
$ ./boolconv
Hello, world


But as Ian remarked, it's better to avoid that.

--
Salu2

Back to top
Tim Clacy
Guest





PostPosted: Tue May 03, 2005 7:52 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Julián Albo wrote:
Quote:
Tim wrote:

Hi. Are you saying that 'operator bool' would be matched in
preference to 'operator int' for an 'if' expression?

Don't checked the standard but gcc accepts it:


// boolconv.cpp

#include
class Convertible {
public:
operator int () { return 0; }
operator long () { return 0; }
operator unsigned int () { return 0; }
operator unsigned long () { return 0; }
operator bool () { return true; }
};

int main ()
{
Convertible c;
if (c)
std::cout << "Hello, world" << std::endl;
}

$ g++ -Wall -pedantic -std=c++98 -o boolconv boolconv.cpp
$ ./boolconv
Hello, world


But as Ian remarked, it's better to avoid that.

Julián,

Cheers. Adding the 'operator bool' has fixed the issue; an 'Event' can used
as Boolean and a Handle now. Why is it better to avoid 'operator bool'?



Back to top
Karl Heinz Buchegger
Guest





PostPosted: Tue May 03, 2005 8:33 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Tim Clacy wrote:
Quote:

Cheers. Adding the 'operator bool' has fixed the issue; an 'Event' can used
as Boolean and a Handle now. Why is it better to avoid 'operator bool'?

The problem with all those conversion operators is that it enables
the compiler to use them even in situations where you don't want them
-> The compiler will use those operators to synthesize expressions which
logically make no sense just to find a way to compile your code at all.

Eg. if a class has an operator bool()

class Test
{
operator bool() { ... }
};

then

Test t;
int i = t + 5;

becomes a valid expression (because false -> 0, true -> 1)

That is exactly why eg. the standard stream classes don't have an operator bool()

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
Tim Clacy
Guest





PostPosted: Tue May 03, 2005 10:24 am    Post subject: Re: T::operator int () const ambiguous with T::operator Hand Reply with quote

Karl Heinz Buchegger wrote:
Quote:
Tim Clacy wrote:

Cheers. Adding the 'operator bool' has fixed the issue; an 'Event'
can used
as Boolean and a Handle now. Why is it better to avoid 'operator
bool'?

The problem with all those conversion operators is that it enables
the compiler to use them even in situations where you don't want them
-> The compiler will use those operators to synthesize expressions
which logically make no sense just to find a way to compile your code
at all.

Eg. if a class has an operator bool()

class Test
{
operator bool() { ... }
};

then

Test t;
int i = t + 5;

becomes a valid expression (because false -> 0, true -> 1)

That is exactly why eg. the standard stream classes don't have an
operator bool()

Hmm, that's pretty disgusting... but couldn't you prevent this kind of
anarchy by defining private operators (e.g. operator + (Event const &, int),
operator + (Event const&, unsigned), etc.). In fact, couldn't you do all the
dirty work in a template?

template<typename T>
class DisableStupidImplicitConversions
{
int operator + (int rhs);
:
};

class Event : DisableStupidImplicitConversions<T>
{
:
};

Are there any other reasons for not defining an 'operator bool'? It seems
like one of the most useful operators for bi-stable objects (like Event,
Interrupt, Timer...).



Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.