Visual Studio 2008 컴파일러가 C ++의 SQRT와 두 배로 자동 캐스트하지 않습니까?
문제
컴파일러가 다음에서 자동으로 두 배로 캐스트해서는 안됩니까? 적어도 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
해결책
문제는 세 가지 버전이 있다는 것입니다 sqrt
에서 고르다:
double sqrt ( double x );
float sqrt ( float x );
long double sqrt ( long double x );
당신이 지나가고 있기 때문에 int
, 컴파일러는 당신의 주장을 홍보 할 것이지만 위의 유형 중 하나에 정수를 홍보하는 것은 똑같이 유효하므로 모호합니다.
다음과 같이 위의 유형 중 하나에 명시 적으로 캐스팅 하여이 문제를 해결할 수 있습니다.
cout << "The square root of k is: " << sqrt((double)k) << endl;
다른 팁
모호한 호출 오류는 암시 적으로 변환되지 않는 것을 호출 할 수있는 기능을 모른다는 것입니다.
다음을보십시오. 더블을 사용하고 두 배를 반환하는 내 자신의 함수를 만들면 암시 적으로 변환하는 문제가 없습니다. 정수는 세 가지 오버로드 중 하나로 변환 될 수 있으므로 무엇을 호출 해야할지 모릅니다.
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
그러나 플로트를 취하는 다른 버전의 MySQRT를 추가하면 모호한 호출 오류가 발생합니다.
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
여러 가지가 있으므로 SQRT 기능 (오버로드) 및 1 이상은 정밀도를 잃지 않고 int를 매개 변수로 받아 들일 수 있습니다. - int를 sqrt로 전달).
C는 SQRTF가 호출되지 않는 한 항상 이중 버전을 반환합니다.
(Double)로 전화를 캐스팅 해보세요
MSDN에서 : [
double sqrt(
double x
);
float sqrt(
float x
); // C++ only
long double sqrt(
long double x
); // C++ only
float sqrtf(
float x
);
]1
cmath에는 std :: sqrt에 몇 가지 과부하가 있습니다. 하나는 플로트를 가져 가고 다른 하나는 두 배를 차지합니다. 컴파일러는 당신이 호출하려는 것을 알 수 없으며, ints는 그들 중 어느 곳에도 캐스팅 될 수 있습니다.
추가 오버로드가 없으면 자동으로 두 배로 두 배로 캐스트됩니다.
예, int에서 더블로 자동으로 캐스트해야합니다. g ++는 이것을 잘 컴파일하므로 VS가 잘못되었다고 생각합니다.
편집 : Mo Answer가 왜 다운 투표를했는지 잘 모르겠습니다. 그러나 C ++에서 기능 과부하 중에 자동 변환은 항상 자동 변환이 가능하다고 생각합니다. 자동 변환이 가능해야합니다. 예 : 플로트로, 플로트 및 두 배로 변환 할 수있는 옵션이있는 경우 항상 int를 이중으로 변환해야합니다.
나는 이것을 G ++에서 시도했으며 SQRT (Double) 함수를 호출하고 있습니다.
#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;
}
따라서 typeid ()의 출력은 "d"이므로 int에서 double으로 자동 변환을 수행했습니다.