Why do i get an error for this ?

C

codefixer

Hi,

Why do I get this error ?
'CRectangle::CRectangle' : ambiguous call to overloaded function

Thanks in advance.


#include <iostream.h>

class CRectangle {
int width, height;
float fw, fh;
public:
CRectangle ();
CRectangle (int,int);
CRectangle (float, float);
int area (void) {return (width*height);}
float area1(void) {return (fw * fh); }
};

CRectangle::CRectangle () {
width = 5;
height = 5;
}

CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}

CRectangle::CRectangle (float a, float b) {
fw = a;
fh = b;
}

int main () {
CRectangle rect (3,4);
CRectangle rectb;
CRectangle rectf(2.5, 2.5);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
cout << "rectf area" << rectf.area1() << endl;
return 0;
}
 
M

Mike Wahler

Hi,

Why do I get this error ?
'CRectangle::CRectangle' : ambiguous call to overloaded function

See below.
Thanks in advance.


#include <iostream.h>

#include <iostream>
#include <ostream>

using std::cout;
using std::endl;
class CRectangle {
int width, height;
float fw, fh;
public:
CRectangle ();
CRectangle (int,int);
CRectangle (float, float);
int area (void) {return (width*height);}
float area1(void) {return (fw * fh); }
};

CRectangle::CRectangle () {
width = 5;
height = 5;
}

CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}

CRectangle::CRectangle (float a, float b) {
fw = a;
fh = b;
}

int main () {
CRectangle rect (3,4);
CRectangle rectb;
CRectangle rectf(2.5, 2.5);

This is the problem line (you should have indicated that in your post).
The reason is that the literal 2.5 has type 'double', there's no
constructor that takes that type, so it cannot determine if you
want those values cast to 'int', or 'float' (the only type arguments
you provided constructors for). The solution is to tell it which to
use:

CRectangle rectf(2.5f, 2.5f); /* the 'f' suffix denotes type 'float' */

(Anyway, you should be using type 'double' instead of 'float'
for your floating point values, unless you have a compelling
reason to do otherwise).
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
cout << "rectf area" << rectf.area1() << endl;
return 0;
}

-Mike
 
V

Victor Bazarov

Why do I get this error ?
'CRectangle::CRectangle' : ambiguous call to overloaded function

Thanks in advance.


#include <iostream.h>

class CRectangle {
int width, height;
float fw, fh;
public:
CRectangle ();
CRectangle (int,int);
CRectangle (float, float);
int area (void) {return (width*height);}
float area1(void) {return (fw * fh); }
};

CRectangle::CRectangle () {
width = 5;
height = 5;
}

CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}

CRectangle::CRectangle (float a, float b) {
fw = a;
fh = b;
}

int main () {
CRectangle rect (3,4);
CRectangle rectb;
CRectangle rectf(2.5, 2.5);

"2.5" is a floating point literal of type 'double'. The compiler
cannot decide whether to make 'float' of them or 'int'. You have
to help it. If you intended to instantiate CRectangle using its
constructor that accepts 'float' arguments, pass float:

CRectangle rectf(2.5f, 2.5f);

Also, it may not be very important in your particular exercise, but
your CRectangle class is not very well designed. The main problem I
see is that I can instantiate a CRectangle using integers and still
call 'area1', which will use _uninitialised_ data members fw and fh,
which can cause CPU to throw a shoe. Perhaps you should look at making
it a template.

V
 
K

Karl Heinz Buchegger

Hi,

Why do I get this error ?
'CRectangle::CRectangle' : ambiguous call to overloaded function

Because the compiler has 2 ways to deal
with construction

In
CRectangle rect(2.5, 2.5);
both numbers are of type double, so you force the
compiler to decide if it takes constructor
CRectangle( int, int );
or it uses constructor
CRectangle( float, float);

Neither constructor matches your argument types (which
are of type double), but the arguments could be converted
to any one of the required data types (int or float).
Both are consider to be equal good matches, thus the
compiler decides to let you clearify.

Best thing:
Throw away the constructor which takes only int.
You don't need it. The one which takes 2 floats
does the very same thing.

Next best thing:
Clearify which constructor you want, by writing
CRectangle rect( 2.5f, 2.5f);
But this leaves another problem. Suppose you want to
write:
CRectangle rect( 2, 3.1415f);
So which constructor should be taken? The one that takes
2 int or the one which takes 2 float? Solution: see
solution one, throw away the constructor taking int.

Also: *** Don't use float ***
Never!
That is: Until you know what you do, have the knowledge
to fight that beast, are willing to fight that beast and
you don't have a very, very, very good reason, always use
data type double and forget that float even exists.
 
C

codefixer

Thanks folks. (For all your thoughts).
I understand constructor cannot accept "float". - By design ?
Your response has created another question in my mind.
Why would I use "double" rather than "float" ? My understanding is
"double" consumes the memory than that of "float" ?

Thanks.
 
V

Victor Bazarov

Thanks folks. (For all your thoughts).
I understand constructor cannot accept "float". - By design ?

Why can't it? How do you derive that from our responses?
Your response has created another question in my mind.
Why would I use "double" rather than "float" ? My understanding is
"double" consumes the memory than that of "float" ?

I take it that you wanted to write <"double" consumes more memory>.

Yes, it can. On your system it probably does. Are you running out of
memory? Until you do (and very likely you never will), do not concern
yourself with using smaller data types just for the sake of using less
memory.

And, please don't top-post. Thanks.

Victor
 
M

Mike Wahler

Thanks folks. (For all your thoughts).
I understand constructor cannot accept "float". - By design ?

Yes, one of your constructors can indeed accept arguments
of type 'float'. The problem was that you did not supply
any arguments of that type.
Your response has created another question in my mind.
Why would I use "double" rather than "float" ?

Because it's guaranteed to have a much larger range
and precision than type 'float'.
My understanding is
"double" consumes the memory than that of "float" ?

It might, it might not, this depends upon the implementation.
Nothing prevents it from having the same range and precision
as 'double'. BUT: its required range and precision are much less.

Even if 'double' does consume more memory than 'float',
does this really matter? How much of a difference does
it really make for your program, and is this difference
really a problem?

BTW please don't top-post.

-Mike
 
K

Karl Heinz Buchegger

Thanks folks. (For all your thoughts).
I understand constructor cannot accept "float". - By design ?
Your response has created another question in my mind.
Why would I use "double" rather than "float" ? My understanding is
"double" consumes the memory than that of "float" ?

Granted. On the other hand double has more precision then float.
What do you prefer: saving memory or running the risc of wrong
results (*)

Try the following program:

#include <iostream>
#include <iomanip>
using namespace std;

int main () {
float a = 12345.12;
float b = 12345.12;

cout << setprecision(15) << a * b << endl;
return 0;
}

When I run it on my computer the output is
152401984

but when I power up my pocket calculator, it tells me that
the correct answer is:
152401987.8144

(Note: Even the immediate digit left of comma is already wrong. 4 versus 7)

See the difference it makes now? (you might try to change float
to double in the above and retest the whole thing).


(*) A similar thing is true for double too. But since double typically has
a lot more precision then float, the 'error' is much smaller.
 
J

Jerry Coffin

Why would I use "double" rather than "float" ? My understanding is
"double" consumes the memory than that of "float" ?

Yes, a double typically consumes more memory. Some computations with
doubles are also marginally slower than with floats.

Unfortunately, a typical float has _such_ limited precision (around six
significant digits at best) that unless you know a _lot_ about
numerical analysis, there's a very strong chance that by the time you
finish an arbitrarily chosen algorithm with floats, you may easily have
only one or two digits left that mean anything -- and there are quite a
few algorithms that can destroy it all, so you get answers that
literally don't mean anythng at all.

Now, it's _possible_ for the same thing to happen with double's as
well, but a double has enough more precision to start with (typically
around 15 digits or so) that it's much easier to maintain sufficient
accuracy.

There was a time, of course,when memory was quite expensive: in 1964
the monthly rent on a 12Kbyte memory module ran over $500US/month. At
that rate, it was well worth spending time and effort to make your
calculations work in a smaller data type. (see:
http://ed-thelen.org/comp-hist/BRL64-p.html for one example of
historical pricing, if you care).

That's not the case anymore though -- memory is cheap. If you know (for
example) that you're going to be storing 100 million of them, it may be
worth the extra trouble to use a float, but otherwise, there's unlikely
to be much reason to mess with it.
 

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,780
Messages
2,569,611
Members
45,278
Latest member
BuzzDefenderpro

Latest Threads

Top