4

编译器不应该在下面自动转换为 double 吗?至少根据沃尔特·萨维奇的说法。

#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
4

6 回答 6

8

问题是有三个版本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;
于 2010-03-16T06:47:26.200 回答
4

模棱两可的调用错误是它不知道要调用哪个函数,而不是它没有隐式转换。

看看以下。如果我创建自己的函数,它接受一个双精度并返回一个双精度,那么隐式转换就没有问题。由于您的整数可以转换为三个重载中的任何一个,因此它不知道要调用什么。

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
于 2010-03-16T06:45:01.820 回答
2

由于有多个sqrt 函数(重载)并且超过 1 个可以接受 int 作为参数而不会失去精度,因此您可以指定哪个(这是一件好事,因为您不希望编译器为您做出决定基于“间接”证据 - 将 int 传递给 sqrt)。

于 2010-03-16T06:48:24.333 回答
0

cmath 中的 std::sqrt 有几个重载。一个是浮点数,另一个是双精度数。编译器不知道你想调用哪个,并且 int 可以转换为其中的任何一个。

在没有额外的重载的情况下,它会自动转换为你所期望的 double [这是 C 中的情况]。

于 2010-03-16T06:48:12.727 回答
0

除非调用 sqrtf,否则 C 始终返回双精度版本。

尝试使用 (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

于 2010-03-16T06:43:33.250 回答
-2

是的,它应该自动从 int 转换为 double。g++ 编译得很好,所以我猜 VS 是错误的

编辑:不知道为什么莫回答被否决。但我认为在 c++ 中的函数重载期间,自动转换应该总是发生在自动转换中的最高数据类型是可能的。例如:如果有从 into 转换为 long、float 和 double 的选项,它应该始终执行 int 到 double 的转换。

我在 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 的自动转换。

于 2010-03-16T06:47:59.607 回答