38

私はしようとしています

void function(int y,int w)
{
    printf("int function");

}


void function(float y,float w)
{
    printf("float function");
}


int main()
{
    function(1.2,2.2);
    return 0;
}

のようなエラーエラーが表示されます..

error C2668: 'function' : ambiguous call to overloaded function

そして、私が呼び出そうとしたとき、function(1.2,2)または「 int functionfunction(1,2.2)として印刷されているとき

function(float y,float w)いつ呼び出されるかを明確にしてください。

4

11 に答える 11

75

gcc からのエラー メッセージを見てください。

a.cpp:16: error: call of overloaded ‘function(double, double)’ is ambiguous
a.cpp:3: note: candidates are: void function(int, int)
a.cpp:9: note:                 void function(float, float)

いずれかの関数を呼び出すには切り捨てが必要になるため、どちらも優先されません。私はあなたが本当に欲しいと思うvoid function(double y,double w). C/C++ では、リテラルとパラメーターの受け渡しのデフォルトの浮動小数点型はfloatではなく doubleであることに注意してください。

アップデート

関数のシグネチャfloatからdoubleに変更したくない場合は、 floatとして型指定されたリテラルをいつでも使用できます。浮動小数点数に接尾辞fを追加すると、float 型になります。

あなたの例は と にfunction(1.2f, 2f)なりfunction(1, 2.2f)ます。

于 2013-05-17T05:48:24.130 に答える
37

演算子のオーバーロードとは何ですか?

Sbi の有名なOperator オーバーロードFAQ は、これに非常に詳細に答えています。

functionOPの 2 つのバージョンの存在が許可されているのはなぜですか?

これらは異なる関数パラメーターの型(intおよびfloat) を取るため、有効な関数オーバーロードとして認定されることに注意してください。

オーバーロードの解決とは何ですか?

これは、コンパイラの実装によって最も適切な関数/演算子を選択するプロセスです。最適な実行可能な関数が存在し、一意である場合、オーバーロードの解決は成功し、結果としてそれが生成されます。そうしないと、オーバーロードの解決が失敗し、呼び出しが不正な形式として扱われ、コンパイラが診断を提供します。コンパイラは、暗黙的な変換シーケンスを使用して、最適な一致関数を見つけます。

C++03 標準 13.3.3.1 暗黙の変換:

暗黙的な変換シーケンスは、関数呼び出しの引数を、呼び出される関数の対応するパラメーターの型に変換するために使用される一連の変換です。

暗黙的な変換シーケンスは、次のカテゴリのいずれかになります。

  • 標準変換シーケンス (13.3.3.1.1)
  • ユーザー定義の変換シーケンス(13.3.3.1.2)
  • 省略記号変換シーケンス (13.3.3.1.3)

これらのそれぞれは、実行可能な最良の機能を決定するためにランク付けされていることに注意してください。最良の実行可能な関数は、すべてのパラメーターが、他のすべての実行可能な関数よりも優れた、または同等のランクの暗黙的な変換シーケンスを持つ関数です。標準では、これらのそれぞれについて、それぞれのセクションで詳しく説明しています。標準の変換シーケンスはこの場合に関連しており、次のように要約されます。

ここに画像の説明を入力

解像度のオーバーロードに関する十分な背景があります。
OP のコード例を調べてみましょう。

function(1.2,2.2);

重要な規則: 1.2 andはリテラルであり、データ型 2.2として扱われます。double

暗黙的な変換シーケンス マッピング中:型
を持つ関数パラメーター リテラルは両方とも、またはバージョンを呼び出すために変換ランクdoubleを必要とし、他よりも一致するものはありません。変換ランクでまったく同じスコアが付けられます。コンパイラは実行可能な最適な一致を検出できず、あいまいさを報告します。 floatint

function(1.2,2);

暗黙的な変換シーケンス マッピング中:
関数パラメーターの 1 つが関数バージョンと完全に一致し、別のパラメーター2変換ランクを持っています。パラメーターとして受け取る関数の場合、両方のパラメーターの暗黙的な変換シーケンスは変換ランクです。 したがって、バージョンよりもスコアが高く、最も一致するバージョンを取る関数が呼び出されます。int1.2float
intfloat

オーバーロードのあいまいなエラーを解決するには?

暗黙の変換シーケンス マッピングにうんざりしたくない場合は、関数を提供し、パラメーターが完全に一致するような方法でそれらを呼び出すだけです。完全一致は他のすべてのスコアよりも高いため、目的の関数が呼び出されるという明確な保証があります。あなたの場合、これを行うには2つの方法があります:

解決策 1:

パラメーターが使用可能な関数と完全に一致するように関数を呼び出します。

function(1.2f,2.2f);

1.2f2.2fは型として扱われるため、関数のバージョンfloatと完全に一致します。float

解決策 2:

呼び出された関数のパラメーターの型と正確に一致する関数のオーバーロードを提供します。

function(double, double){}

1.22.2は呼び出された関数として扱われるためdouble、このオーバーロードと完全に一致します。

于 2013-05-17T05:44:42.620 に答える
7

したくない場合(受け入れられた回答で説明されているように):

  • float リテラルを使用します。1.2f
  • または既存のfloatオーバーロードを次のように変更しますdouble

float を呼び出す別のオーバーロードを追加できます。

void function(double y, double w)
{
    function((float)y, (float)w);
}

あなたのコードはmain、オーバーロードを呼び出す上記の関数を呼び出しますfloat

于 2013-05-31T21:41:26.857 に答える
4

上記の例の関数のオーバーロードにはあいまいな呼び出しがあります。これは、戻り値の型が同じで、関数呼び出しの 2 番目の引数が double であり、int または float として処理できるため、コンパイラが実行する関数を混同するためです。

于 2013-05-17T08:06:48.520 に答える
2

プリミティブ型を引数として関数に送信する場合、送信するプリミティブ型が要求とまったく同じでない場合は、常に要求されたプリミティブ型にキャストする必要があります。

int main()
{
    function(1.3f,                    2.4f);
    function(1.3f,                    static_cast<float>(2.4));
    function(static_cast<float>(1.3), static_cast<float>(2.4));
    function(static_cast<float>(1),   static_cast<float>(2));
    return 0;
}
于 2013-05-17T08:33:41.817 に答える
2

デフォルトでは、10 進数は double と見なされます。10 進数を浮動小数点数にしたい場合は、末尾に f を付けます。function(1.2,2.2) を呼び出すときの例では、コンパイラは渡した値を double と見なすため、関数の署名が一致しません。

function(1.2,1.2) ====> function(double,double)

関数シグネチャを保持したい場合は、浮動小数点リテラルを渡すときに浮動小数点サフィックスを使用する必要があります。

function(1.2f,1.2f) ====>   function(float,float).

浮動小数点リテラルについてもっと知りたい場合は、参照できます

MSVC で 3.14 などの浮動小数点値がデフォルトで double と見なされるのはなぜですか?

于 2013-06-05T13:12:24.530 に答える
1

他の人が言ったように、 floats用に設計されたオーバーロードされた関数にdoublesを与えます。オーバーロード自体にはエラーはありません。

オーバーロードされた関数の正しい使い方は次のとおりです (数字の直後の「f」に注意してください)。

function(1.0f, 2.0f);
于 2013-06-05T17:30:01.263 に答える