Overloading a function in C++ [duplicate] - c++

This question already has an answer here:
Using float gives "call to overloaded function is ambiguous" error [duplicate]
(1 answer)
Closed 6 years ago.
I'm learning C++ through Sololearn. I have a doubt about function overloading
this is the code
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
int a =3;
float b = 2.65;
printSomething(a);
printSomething(b);
return 0;
}
it gives output as
I'm printing an integer 3
I'm printing a float 2.65
but if I directly give argument when calling function
like this
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
printSomething(3);
printSomething(2.65);
return 0;
}
i get following error
..\Playground: In function 'int main()':
..\Playground:19:24: error: call of overloaded 'printSomething(double)' is ambiguous
printSomething(2.65);
^
..\Playground:19:24: note: candidates are:
..\Playground:5:6: note: void printSomething(int)
void printSomething(int x) {
^
..\Playground:9:6: note: void printSomething(float)
void printSomething(float x) {
^
but if I change
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
to
void printSomething(double x) {
cout << "I'm printing a float " << x << endl;
}
I will get output as
I'm printing a float 2.65
why is it?
but if it's only the integer it works fine
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
printSomething(3);
return 0;
}
Result
I'm printing an integer 3
Why isn't this working with float
Thankyou

2.65 is not a float literal, it's a double literal.
So the compiler doesn't know whether you want to convert the double to a float or an int and so issues the error.
In your first case, when writing float b = 2.65; the compiler assumes you know what you're doing, and calling the overload with b is unambiguous.
If you had written printSomething(2.65f); then that would also have been unambiguous: 2.65f is a float literal.

2.65 is considered a double. But you didn't provide an overload void printSomething(double x). Therefore the compiler must cast the value and it doesn't know if it should cast to float or int (both with precision loss`).
If you write 2.65f it is considered a float and it should work.

The reason for that is the conversion rules and overload resolution strategy. If C++ is unable to find an exact match on parameters, it looks for a conversion. The best conversion is an implicit one, that is widening (casting a data type to one that can hold all the values of the original type and potentially more), then a narrowing conversion (casting to a smaller data type, which may cause errors or loss of precision for some values), then a user-defined conversion.
As literal 2.65 is of type double, the compiler looks for conversions. There are two: double -> float and double -> int. They are both narrowing, which means they are equally good. The compiler is unable to pick the best one, thus reports an error.
To remedy this, you can either:
define overload for double as you did
use a float literal (2.65f) instead of a double

Related

Why does this program in c++, visual studio code shows error

//function overloading
#include <iostream>
using namespace std;
//declaration of function protype
int area(int);
int area(int, int);
float area(float);
int main()
{
cout << "calling the area() function for computiong the area of a square (side=5) - " << area(5) << "\n";
cout << "calling the area() function for computiong the area of a rectangle (length = 5, bredth = 10) - " << area(5, 10) << "\n";
cout << "calling the area() function for computiong the area of a cirlce (radius 5.5) - " << area(5.5) << "\n";
return 0;
}
int area(int side)
{
return (side * side);
}
int area(int length, int breadth)
{
return (length * breadth);
}
float area(float radius)
{
return (3.14 * radius * radius);
}
error
program4_5.cpp: In function 'int main()':
program4_5.cpp:14:106: error: call of overloaded 'area(double)' is ambiguous
14 | cout << "calling the area() function for computiong the area of a cirlce (radius 5.5) - " << area(5.5) << "\n";
| ^
program4_5.cpp:6:5: note: candidate: 'int area(int)'
6 | int area(int);
| ^~~~
program4_5.cpp:8:7: note: candidate: 'float area(float)'
8 | float area(float);
| ^~~~
PS C:\Users\hasht\Desktop\coding\OOP with c++>
this code while compiling shows function overloading error but from what I know it's correct as I have defined the float area( float radius) function. Can anyone explain why this error occurs. I am new to coding and i don't know how to fix this.
5.5 is a literal of type double, so the compiler doesn't know you want to call the overload taking an int or the one taking a float.
You can use a float-literal instead:
// -V-
cout << "..." << area(5.5f) << "\n";
Type area(5.5f) to force the value to be a float.
The compiler does not know if it should cast your double value to an int or a float. Therefore, it is ambiguous.

Why address gotten from the pointer is always the same? [duplicate]

This question already has answers here:
How to print function pointers with cout?
(7 answers)
Closed 2 years ago.
I am a bit confused now. So, if i write the following code:
int x = 5;
cout << &x << endl;
compile it and run, I'll get something like 0x920FC7D which is the normal hexadecimal value for memory locations. But when I compile and run the following code:
#include <iostream>
using namespace std;
void add(int a, int b){
cout << a + b << endl;
}
void subtract(int a, int b){
cout << a - b << endl;
}
void multiply(int a, int b){
cout << a * b << endl;
}
int main(){
void ( *operations[3] ) (int, int) = {add, subtract, multiply};
int length = sizeof(operations)/sizeof(operations[0]);
for(int i=0; i < length; ++i){
cout << operations[i] << endl;
}
return 1;
}
I always get:
1
1
1
It seems the address of pointer should also be hexadecimal value, but even if it's binary or just decimal, why it is always the same?
If you take a look at the overloads for the operator << with a std::ostream& as the left hand operand, you'll find that there are no overloads for pointers to functions as right hand operand.
But you are inserting function pointers. So, what is being inserted? Well, function pointers are implicitly convertible to bool, and there is an overload for bool. All are 1 because all of the converted values are true. This is because none of the function pointers were null which is the only function pointer that converts to false.

How function double,int work? c++

Could you explain me how these functions work?
double f(int i)
{
cout<<"a";
return 1;
}
int f(double i)
{
cout<<"b";
return 1;
}
For:
f(f(f(1)));
In my opinion the result should be: aaa
but it isaba
And same situation with f(f(f(1.1)));
I think there should be aab but there is bab
When you return from a function, the type of the return value is determined from the function prototype, not what it's written as-is. If the type doesn't match, it'll be implicitly converted to the correct type. So this example function:
double foo(void) { return 1; }
Actually returns double(1), or equivalently, 1.0. It does not return an int because 1 is int. It does, however, convert your int to a double value to match the function's return value type as declared.
So coming to your question, the innermost function called is double f(int), and the second function called is int f(double), and the outermost function called is double f(int). This matched the output you see: aba.
f( f( f(1) ) );
↑ ↑ ↑
| | calls double f(int)
| calls int f(double)
calls double f(int)
The way the compiler reads your f(f(f(1))); function is from the inside out. Let me elaborate, the compiler sees f(1); and it looks for a function called f that takes an int as an argument so that would be:
double f(int i)
{
cout<<"a";
return 1;
}
Now, once your function executes, it returns a double, hence the second f takes in a double -> which calls your next function that takes double
int f(double i)
{
cout<<"b";
return 1;
}
Following the logic explained above, we have arrived at the last/outer layer of your triple f question. Now the compiler has an int and is looking for a function called f that takes int -> which is your first declared function.
And that is why you get aba as a result.
prior to your first use of std::cout in your code, add the line
std::cout << std::fixed;
This changes the output (of parameter i) quite a bit by causing int and double to show their 'true colors'. Perhaps this will illustrates what is happening.
Example:
double f(int i)
{
std::cout << " a" << std::setw(9) << i << " " << std::flush;
return 1;
}
int f(double i)
{
std::cout << " b" << std::setw(9) << i << " " << std::flush;
return 1;
}
int main(int , char** )
{
std::cout << std::fixed << "\n";
f(f(f(1)));
std::cout << std::endl;
f(f(f(1.0)));
return 0;
}
Generates output:
a 1 b 1.000000 a 1
b 1.000000 a 1 b 1.000000
The returned value (always integer 1) is implicitly transformed to the return type, which is different for the two functions.
Which function is invoked is determined by the signature of the function, i.e. the parameters actual type. This also illustrates that the return type is not part of the signature.

Dev c++ 5.11 on Windows 8 Produces wrong answer

#include<iostream>
#include<conio.h>
class Number
{
private:
int x, y;
public:
Number()
{
x = y = 100;
}
void avg()
{
std::cout<<"x = "<<std::cout<<x;
std::cout<<std::endl;
std::cout<<"Y = "<<std::cout<<y;
std::cout<<std::endl;
std::cout<<"Average = "<<std::cout<<(x+y)/2;
}
};
main()
{
Number n;
n.avg();
}
This programme runs but shows wrong answer, may be showing addresses of memory locations instead of showing the assigned values of 100. Please correct me why it is behaving like this?
std::cout << "x = " << std::cout << x;
is wrong. You need
std::cout << "x = " << x;
Otherwise, the std::cout stream object in ...<< std::cout is implicitly converted to a (void*) when invoking operator<< on it, and therefore the pointer (an address) is displayed.
The conversion to void* exists for historic reasons (the safe bool idiom), but in C++11 was removed, due to the introduction of explicit conversion operators, so your code should not compile in C++11.

trouble with error code

/* This program */
using namespace std;
#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>
void readit();
void calcit(int, int);
void writeit(float, float, float);
int distvels[4] = {15, 25, 35, 45};
int main()
{
readit();
system("pause");
return 0;
}
void readit()
{
int targetdist, angl;
cout << "Enter the distance (meters) to the target:" << endl;
cin >> targetdist;
cout << "Enter the angle to fire the cannon:" << endl;
cin >> angl;
cout << "\n---------------\n\n";
calcit (targetdist, angl);
}
void calcit(int targetdist, int angl)
{
double distvals[4];
double tyme[4];
double maxhite[4];
for (int i=0; i<4; i++) {
distvals[i] = (2 * sin(angl) * cos(angl) * (distvels[i] * distvels[i]))/9.8;
tyme[i] = (2 * cos(angl) * distvels[i])/9.8;
maxhite[i] = ((cos(angl) * cos(angl)) * (distvels[i] * distvels[i]))/9.8;
}
writeit(distvals, tyme, maxhite);
}
void writeit(float distvals[4], float tyme[4], float maxhite[4])
{
cout << "Velocity " << "time " << "height " << "distance " <<endl;
for (int i=0; i<4; i++) {
cout << distvals[i] << " " << tyme[i] << " " << maxhite[i] << " " << endl;
}
whenever I run the program I keep getting this error code cannot convert double* to float for argument 1 to void writeit(float, float, float). I've tried everything I can think of to get rid of it with no luck. Can anyone help?
You declared the function as:
void writeit(float, float, float);
but the definition has it as:
void writeit(float distvals[4], float tyme[4], float maxhite[4])
{
// ...
}
Fix the declaration to match:
void writeit(float[4], float[4], float[4]);
It's also worth pointing out at this juncture that this doesn't do what you think it does. In fact, it's the same as this:
void writeit(float[], float[], float[]);
which is the same as this:
void writeit(float*, float*, float*);
That's because you can't pass an array by value, so it degrades into a pointer-to-the-start-of-the-array instead.
However, you can pass it by reference and keep the dimensions:
void writeit(float (&)[4], float (&)[4], float (&)[4]); // declaration
void writeit(float (&distvals)[4], float (&tyme)[4], float (&maxhite)[4]) // definition
{
// ...
}
I'd even recommend passing it as reference-to-const, as you won't be changing it:
void writeit(float (&)[4], float (&)[4], float (&)[4]);
void writeit(const float (&distvals)[4], const float (&tyme)[4], const float (&maxhite)[4])
{
// ...
}
It would also be easier if you used a std::vector<float>, but that's another discussion.
Plenty to think about there; hope it helps.
Edit Just noticed another problem, in that you're trying to pass an array of double to a function that will be expecting an array of float! Pick one and stick with it.
The error is exactly as you note -- writeit is expecting a pointer to an array of floats and you're trying to pass it an array of doubles, which are a different size. The easiest fix would be to declare the args of writeit to be arrays of doubles, so they match. Barring that, you need to copy to arrays of floats before passing (converting each element as you copy)
The function prototype is different from the function definition. So, change it to -
void writeit(double*, double*, double*);
And the function definition to -
void writeit(double distvals[], double tyme[], double maxhite[])
{
// ......
}
Notice that the array size (i.e., optional, in fact compiler won't consider it) because array decays to a pointer. It is the reason why usually array size is also sent as an argument to the functions and is a good practice.