Ambiguity error using overload in c++ - c++

I have tried to use overload with floating and integer. When I only used the integer, the code worked fine, but when I included the floating it gave me errors. The code is the following:
#include <iostream>
using namespace std;
int calculate(int x,int y);
float calculate(float x,float y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
float fresult=calculate(7.5,7.5); LINE X
cout << (result + MAININT + fresult); LINE Y
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
float calculate(float x,float y)
{
int result=x*y;
return result;
}
By deleting LINE X and fresult from LINE Y, the code give me no errors. So I assume there must be something wrong in LINE X, but I don't understand why I get errors.
The error messages I got was :
[Error] call of overloaded 'calculate(double, double)' is ambiguous
[Note] candidates are:
[Note] int calculate(int, int)
[Note] float calculate(float, float)
I did not understand the error messages, so I didn't include them. I understand what I did wrong from the answer of songyuanyao, but next time I will include the error messages in my question from the start so it will be easier to see what I have done wrong in the code.

Because 7.5 is a double (see floating point literal), not a float; and implicit conversion to int or float are considered as the same ranking.
If your suppose 7.5 as float here you could use the suffix f or F to make it a float literal. e.g.
float fresult = calculate(7.5f, 7.5f); // 7.5f is a float literal; no ambiguity
Or use explicit conversion:
float fresult = calculate(static_cast<float>(7.5), static_cast<float>(7.5));

You should have posted the error message which is self-explanatory in itself. The error message mentions about the candidate functions and how they are not exactly compatible:
error: call of overloaded 'calculate(double, double)' is ambiguous
float fresult=calculate(7.5,7.5);
^
note: candidate: int calculate(int, int)
int calculate(int x,int y);
^
note: candidate: float calculate(float, float)
float calculate(float x,float y);
By default, a floating-point literal (7.5 in your case) is of type double.
Here is the list of suffix that determines the type of the floating-point literal:
(no suffix) defines double
f F defines float
l L defines long double

While others have already told you where the ambiguity error comes from, I'm surprised nobody has mentioned the easiest solution to the problem: Just use double instead of float.
Just like int should be your default choice for integer numbers, double should be your default choice for floating-point numbers. float is for very special use cases, none of which are likely to apply in your situation. See "When do you use float and when do you use double" over at Software Engineering Stack Exchange.
As a side effect of following this guideline, your particular problem here disappears:
#include <iostream>
using namespace std;
int calculate(int x,int y);
double calculate(double x, double y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
double fresult=calculate(7.5,7.5);
cout << (result + MAININT + fresult);
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
double calculate(double x, double y)
{
double result=x*y; // the `int` here was a mistake in your original code anyway
return result;
}
Some further suggestions:
Avoid using namespace std;.
Reserve ALL_CAPS for preprocessor macros.

Related

How can I pass the value from void function in one cpp file to an other void function in an other cpp file?

I am very new to programming but i have to do this for my project.
In Visual C++ 6.0, I am trying to send the calculated value from one function to the other in a different cpp file.
however, when I try to compile I get the following error :
Creating library Debug/usradd.lib and object Debug/usradd.exp
addrxn.obj : error LNK2001: unresolved external symbol "float * Gamma"
(?Gamma##3PAMA) ..\debug\usradd.dll : fatal error LNK1120: 1
unresolved externals
How can I fix this problem? Thank you.
This is simple version of code that I tried.
I like to pass Gamma matrix from addk.cpp to addrxn.cpp as shown below.
Thank you.
//callccx.h
//declare "Gamma" array
extern Gamma[23];
//addk.cpp
void addk(float *y, float *x, double t, double p, float *xkv)
{
float Gamma[1] = 2000*t;
.
.
.
float Gamma[23] = 2300*t;
for(int i=0;int<23;i++)
{
xkv[i] = 200*t/p*Gamma[i];
}
return;
}
//addrxn.cpp
int addrxn0(const int nUopID, const int nRxnID, const int nComponents,
const double fTemperature, const double fPressure, const double fRPM,
const double fBetaFac, const double fFreqFac, const double fExpActE,
const double *C, const double *Pi, const double *fStoich,
const double *fExponent, const double *fAdsFac, const double *fAdsE,
const double *fAdsExp, double *pRateForm)
{
//Arhenius
double rate=fExpActE*fFreqFac*Gamma[1]/Gamma[2];
int iComp;
for(iComp=0;iComp<nComponents;iComp++)
{
if(fStoich[iComp] < 0)
{ //This is a reactant.
if(fExponent[iComp] == 0.0)
rate*=pow(C[iComp], -fStoich[iComp]); //Use stoich as exponent
else
rate*=pow(C[iComp], fExponent[iComp]); //Use exponent as given
}
}
//Final rate of formation
(*pRateForm)=rate*
return 0;
}
The extern declaration requires a type:
extern float Gamma[23];
Your sample code:
float Gamma[1] = 2000*t;
makes no sense. Are you declaring a float array of ONE element here? You probably meant:
Gamma[1] = 2000 * t;
Anyway, your link error tells you that Gamma needs to be defined somewhere, probably in another file. Something like
float Gamma[23];

How to fix "error: call to 'abs' is ambiguous"

I'm running a simple C++ program from HackerRank about pointers and it works fine on the website. However,
when I run it on MacOS, I get error: call to 'abs' is ambiguous and I'm not sure exactly what is ambiguous.
I've looked at other answers to similar issues, but the error message tends to be Ambiguous overload call to abs(double), which is not the issue I'm having, since I haven't used any doubles. I've also tried including the header files cmath and math.h, but the problem persists.
#include <stdio.h>
#include <cmath>
void update(int *a,int *b) {
int num1 = *a;
int num2 = *b;
*a = num1 + num2;
*b = abs(num1 - num2);
}
int main() {
int a, b;
int *pa = &a, *pb = &b;
scanf("%d %d", &a, &b);
update(pa, pb);
printf("%d\n%d", a, b);
return 0;
}
My issue occurs with line 8.
The full error message is:
$ clang++ test.cpp
test.cpp:8:10: error: call to 'abs' is ambiguous
*b = abs(num1 - num2);
^~~
.../include/c++/v1/math.h:769:1: note: candidate function
abs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(double __lcpp_x) _NOEXCEPT {return ::fabs(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.
The three overloads of abs that you have from <cmath> are abs(float), abs(double) and abs(long double); it's ambiguous because you have an int argument and the compiler doesn't know which floating-point type to convert to.
abs(int) is defined in <cstdlib>, so #include <cstdlib> will resolve your problem.
If you're using Xcode, you can get more details about the error in the Issues navigator (⌘5) and clicking the triangle next to your issue.
For me, #include <cstdlib> didn't solve the issue, maybe because I didn't have to include anything to use abs. So, in case it helps someone else, with explicit casting, it worked well for me like in the next code:
*b = abs(int(num1 - num2));
In templated code, it may be easily overlooked that std::abs is not defined for unsigned types. As an example, if the following method is instantiated for an unsigned type, the compiler may rightfully complain that std::abs is undefined:
template<typename T>
bool areClose(const T& left, const T& right) {
// This is bad because for unsigned T, std::abs is undefined
// and for integral T, we compare with a float instead of
// comparing for equality:
return (std::abs(left - right) < 1e-7);
}
int main() {
uint32_t vLeft = 17;
uint32_t vRight = 18;
std::cout << "Are the values close? " << areClose(vLeft, vRight) << std::endl;
}
A better definition of areClose() in above code, that would coincidentally also solve the problem of std::abs() being undefined, could look like this:
template<typename T>
bool areClose(const T& left, const T& right) {
// This is better: compare all integral values for equality:
if constexpr (std::is_integral<T>::value) {
return (left == right);
} else {
return (std::abs(left - right) < 1e-7);
}
}
if your using C compiler you should include
#include <stdlib.h>
and use abs without std::.
If you use C++ compiler then you should change abs to std::abs.
Hope it helps:)
I used #include <bits/stdc++.h> as the only include statement and it worked for me.
My code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int n = nums.size();
if(n == 0 || n == 1)
return {};
vector<int> ans;
for(int i = 0; i < n; i++)
{
if(nums[abs(nums[i])-1] < 0)
ans.push_back(abs(nums[i]));
else
nums[abs(nums[i])-1] = -1 * nums[abs(nums[i])-1];
}
return ans;
}
};

Function overloading in C++. Does not work with float, works with double [duplicate]

This question already has an answer here:
Using float gives "call to overloaded function is ambiguous" error [duplicate]
(1 answer)
Closed 7 years ago.
#include <iostream>
using namespace std;
int square(int x);
float square(float x);
int main() {
cout<<square(3);
cout<<square(3.14);
return 0;
}
int square(int x) {
cout<<"\nINT version called\n";
return x*x;
}
float square(float x) {
cout<<"\nFLOAT version called\n";
return x*x;
}
I have tried to replace the float version of a function with double one, and it starts to work then. What is the problem here? Cannot 3.14 be considered as float?
error: call of overloaded 'square(double)' is ambiguous
note: candidates are:
note: int square(int)
note: float square(float)
Floating-point literals in C++ are of type double. Conversions from double to int and float do not have an ordering defined, so your call is ambiguous.
If you want to call the float function, call it with a float literal:
cout<<square(3.14f);
//note the f here^
3.14 is taken as a double by the compiler . It does not find a function with double argument and is confused if it should convert the double to int or float .Therefore either try below code or use double in function declaration.
cout<<square(3.14f);

C++ - Deriving Classes - Error: expected primary expression before'int'

First post so be gentle with me...
I am trying to implement a derived class and am having problems and no matter what i try am getting compilation errors. I am sure it is something simple i have missed but am very new to this and all my research has given me no help (or i have just missed it cause i dont know what I am doing!).
This is my header file:
#ifndef WEEKDAY_H
#define WEEKDAY_H
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
class DateTime{
public:
DateTime(int y, int m, int d, int h = 0, int min = 0, int s = 0);
void display();
protected:
string get_string_component(char option, tm* dateStruct);
int get_year_days(tm* dateStruct);
struct tm DTstruct;
private:
bool validate_data( int y, int m, int d, int h, int min, int s);
};
class WeekDay : public DateTime{
public:
WeekDay(int y, int m, int d, int h = 0, int min = 0, int s = 0);
void display();
};
#endif
This is an excerpt from the .cpp file that i am trying to implement:
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(int y, int m, int d, int h, int min, int s),{
}
void WeekDay::display(){
}
At present I am getting the following error:
weekday.cpp: In constructor 'WeekDay::WeekDay(int, int, int, int, int, int)':
weekday.cpp:58:13: error: expected primary-expression before 'int'
weekday.cpp:58:20: error: expected primary-expression before 'int'
weekday.cpp:58:27: error: expected primary-expression before 'int'
weekday.cpp:58:34: error: expected primary-expression before 'int'
weekday.cpp:58:41: error: expected primary-expression before 'int'
weekday.cpp:58:50: error: expected primary-expression before 'int'
weekday.cpp:60:1: error: expected identifier before '{' token
If i change things around in the .cpp file i get different errors - obviously.
Basically i really don't know how to do this and have struggled trying to find the correct way...
Anyway if someone can point me in the right direction it would be greatly appreciated...
Thanks
You're using the member initialization list incorrectly. If you want to pass the values of the arguments passed to the WeekDay constructor to the constructor of DateTime, you need to remove the types:
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(y, m, d, h, min, s) {
}
Consider it like calling a function (because actually, that's what it's doing). If you have a function like void foo(int x);, you don't call it by writing foo(int 5), do you?
: DateTime(int y, int m, int d, int h, int min, int s),{
remove all the "int"s from that line.
this line:
: DateTime(int y, int m, int d, int h, int min, int s),{
should be:
: DateTime(y, m, d,h, min,s) {
The offending line is this one:
: DateTime(int y, int m, int d, int h, int min, int s),{
First you have a trailing comma before the ,, then you should remove the int you put in this line: you are not defining the superclass constructor, but calling it. Think of this as an ordinary (unbound) function: you call functions with f(x), not f(int x).
The member-initializer list takes a comma separated list of data members and initializes it with the parameter you supply. int x is not a value, it's actually a syntax error in this case. However, x would be a value.
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(y, m, d, h, min, s)

C++ redifinition of'..' and previously declared here errors

I have already searched for this type of error and found a few threads, but each one recommended using #ifndef to make sure the header file is only loaded once. I have done this and still get an error. The odd thing is this error:
circle.cc:25:6: error: prototype for ‘void circle::populate_classobj(int, int, int)’ does not match any in class ‘circle’
says my function only has 3 int's but every place i have that function, i have 4 ints.
here is my class header file
#ifndef _CIRCLE_H_
#define _CIRCLE_H_
#define PI 3.14159
class circle
{
public:
float radius(int x1, int x2, int y1, int y2);
float circumference(float d);
float area(float d);
void populate_classobj(int, int, int, int);
protected:
float distance(int x1, int x2, int y1, int y2);
private:
int x1, y1, x2, y2;
};
#endif // _CIRCLE_H_
Here is my function call in my class file circle.cc
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
{
x1=cx1;
x2=cx2;
y1=cy1;
y2=cy2;
}
and here is what i actually call in main
mycircle.populate_classobj(x1,x2,y1,y2);
there are variables called x1, x2, y1, y2 in main
The really odd thing is that the redefinition error is only for cy1, not cx1, cx2 or cy2
Thanks for any help and if you need to see more of my code, ask for it.
-Will
Last two parameters are exactly same as shown below. Hence the redefinition error.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
^^^ ^^^
I think you wanted to write:
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy2)
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
You see there the redefinition of cy1, since both last arguments are called the same. By the way, names beginning with an underscore in the global namespace are reserved for the implementation, you should drop the leading underscore from your scope guards.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
// ^^^ ^^^
Is this a question typo, or do you really have two parameters in the function definition named cy1?
Your definition of populate_classobj uses the same name cy1 for two different parameters.