Shouldn't the compiler automatically cast to a double in the following? At least according to Walter Savitch.
开发者_高级运维#include <iostream>
#include <cmath>
using namespace std;
int main(){
int k;
for(k = 1; k <= 10; k++)
cout << "The square root of k is: " << sqrt(k) << endl;
return 0;
}//error C2668: 'sqrt' : ambiguous call to overloaded function
//Visual Studio 2008 on Win Vista
The problem is that there are three versions of sqrt
to choose from:
double sqrt ( double x );
float sqrt ( float x );
long double sqrt ( long double x );
Since you're passing in an int
, the compiler is going to promote your argument but it's equally valid to promote your integer to any of the above types, so it's ambiguous.
You can fix this by simply explicitly casting to one of the above types, as in:
cout << "The square root of k is: " << sqrt((double)k) << endl;
Ambiguous call error is that it doesn't know which function to call not that its not implicitly converting.
look at the following. If I create my own function that takes a double and returns a double it has no issue implicitly converting. Since your integer can be converted to any of three overloads it doesn't know what to call.
double mysqrt(double d)
{
return d;
}
using namespace std;
int main(int argc, char ** argv)
{
int k;
for(k = 1; k <= 10; k++)
cout << "The square root of k is: " << mysqrt(k) << endl;
return 0;
}//Works Fine
However if I add another version of mysqrt that takes a float I create an ambiguous call error.
double mysqrt(float f)
{
return f;
}
double mysqrt(double d)
{
return d;
}
using namespace std;
int main(int argc, char ** argv)
{
int k;
for(k = 1; k <= 10; k++)
cout << "The square root of k is: " << mysqrt(k) << endl;
return 0;
}//error C2668: 'mysqrt' : ambiguous call to overloaded function
Since there are multiple sqrt functions (overloads) and more than 1 can accept an int as a parameter without loosing precision it is up to you to specify which (and this is a good thing because you don't want the compiler taking decisions for you based on 'circumstantial' evidence - passing an int to sqrt).
C always returns the double version unless sqrtf is called.
Try casting your call with (double)
From the MSDN: [
double sqrt(
double x
);
float sqrt(
float x
); // C++ only
long double sqrt(
long double x
); // C++ only
float sqrtf(
float x
);
]1
There are several overloads to std::sqrt in cmath. One takes a float and another takes a double. The compiler can't know which you want to be called, and ints can be cast into any of them.
In the absence of the additional overloads, it would automatically cast to double [this is the case in C] as you expect.
Yes, It should automatically cast from int to double. g++ compiles this fine so I guess VS is wrong
EDIT: not sure why mo answer is down-voted. But I think during function overloading in c++, automatic conversion should always happen to a highest data type in auto conversion is possible. for ex: if there is an option to convert from into to long,float and double, it should always does an int to double conversion.
I tried this in g++ and it is calling sqrt(double) function.
#include <iostream>
#include <cmath>
#include <typeinfo>
using namespace std;
int main(){
int k;
for(k = 1; k <= 10; k++)
cout << "The square root of k is: " << sqrt(k) <<' '<< typeid(sqrt(k)).name()<< endl;
return 0;
}
So output of typeid() is "d" which means it has done an auto conversion from int to double.
精彩评论