472,371 Members | 1,470 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

T::operator int () const ambiguous with T::operator Handle () const?

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;
};
Jul 23 '05 #1
15 4225

Tim Clacy wrote:
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.

private:
Handle handle;
};


Jul 23 '05 #2
Shezan Baig wrote:
Tim Clacy wrote:
typedef struct tagHandle { }* Handle;
try instead:
struct Handle { SomeType* realHandle; };
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.


Jul 23 '05 #3
On Fri, 29 Apr 2005 18:45:08 +0200, "Tim Clacy"
<no*******@nospamphaseone.nospamdk> wrote:
Please illuminate; what operator of class 'Event' will get matched for these
two cases [see Event outline later]:
[...]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)?

Shezan Baig summed up the ambiguity. As for what to do, I'd define
'Event::operator bool() const'.

Kanenas
Jul 23 '05 #4
ben
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();
}

//...
};
Jul 23 '05 #5
Tim

<ab*********@spambob.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
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?
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?
Jul 23 '05 #6
Tim

"ben" <be******@hotmail.com> wrote in message
news:42**********************@news.optusnet.com.au ...
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
Jul 23 '05 #7
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
Jul 23 '05 #8
Tim wrote:

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)
Jul 23 '05 #9
Ian
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.

Ian
Jul 23 '05 #10
Ian wrote:
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
Jul 23 '05 #11
Tim
"Julián Albo" <JU********@terra.es> wrote in message
news:42********@x-privat.org...
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?
Jul 23 '05 #12
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 <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
Jul 23 '05 #13
Julián Albo wrote:
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 <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.


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'?
Jul 23 '05 #14
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()

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #15
Karl Heinz Buchegger wrote:
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...).
Jul 23 '05 #16

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

Similar topics

4
by: Alex Vinokur | last post by:
Why is it ambiguous? ------ foo.cpp ------ struct Foo { Foo operator* (Foo) { return Foo(); } Foo operator* (int) const { return Foo(); } Foo () {} Foo (int) {} };
5
by: Gianni Mariani | last post by:
Can anyone enligten me why I get the "ambiguous overload" error from the code below: friendop.cpp: In function `int main()': friendop.cpp:36: ambiguous overload for `std::basic_ostream<char,...
0
by: A. W. Dunstan | last post by:
I'm porting some code to Visual C++ and have run into a problem - the compiler won't use a user-written cast operator. The code uses an envelope-letter approach to passing (potentially) large...
1
by: Tony Johansson | last post by:
Hello! I have this wrapper class Integer below that I use when testing operator overloading. A book that I read say that the expression Integer i; i+5 is translated to operator+(i,5) using the...
1
by: Tony Johansson | last post by:
This class template and main works perfectly fine. But could be better. I have this class template called Handle that has a pointer declared as T* body; As you can see I have a reference counter...
19
by: scroopy | last post by:
Is it impossible in C++ to create an assignment operator for classes with const data? I want to do something like this class MyClass { const int m_iValue; public: MyClass(int...
7
by: Jim Langston | last post by:
This is something someone was asking in irc. I really don't need to do this right now, but may have to in the future. The following code is in error (marked). #include <iostream> #include...
11
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. ...
4
by: abendstund | last post by:
Hi, I have the following code and trouble with ambiguity due to operator overloading.. The code is also at http://paste.nn-d.de/441 snip>>
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...

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.