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

問題は、次の3つのバージョン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を受け取り、doubleを返す独自の関数を作成した場合、暗黙的に変換しても問題はありません。整数は3つのオーバーロードのいずれかに変換できるため、何を呼び出すべきかわかりません。

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

ただし、floatを使用する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

sqrtfが呼び出されない限り、Cは常にdoubleバージョンを返します。

(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 に答える
0

cmathのstd::sqrtにはいくつかのオーバーロードがあります。1つはフロートを取り、もう1つはダブルを取ります。コンパイラーは、どちらを呼び出したいかを知ることができず、intをそれらのいずれかにキャストすることができます。

追加のオーバーロードがない場合は、期待どおりに自動的に2倍にキャストされます[これはCの場合です]。

于 2010-03-16T06:48:12.727 に答える
-2

はい、intからdoubleに自動的にキャストする必要があります。g ++はこれをうまくコンパイルするので、VSは間違っていると思います

編集:なぜmoの答えが反対票を投じられているのかわからない。しかし、C ++での関数のオーバーロード中は、自動変換は常に可能な限り最高のデータ型に行われるべきだと思います。例:から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 に答える