2011-12-31 16 views
4
#include <iostream> 
#include <cmath> 
using namespace std; 

float f (int a, int b) { 
    return (a + b); 
} 

float f (float a, float b) { 
    return (round(a + b)); 
} 

int main() 
{ 
    cout << "Hello World!" << endl; 
    int int1 = 1; 
    int int2 = 2; 
    float float1 = 1.2f; 
    float float2 = 1.4f; 
    cout << f(int1, int2) << endl;  // output: 3 
    cout << f(float1, float2) << endl; // output: 2 
    cout << f(int1, float2) << endl; // output: 2 
    return 0; 
} 
  1. なぜ最後の出力は、fの2番目の定義を使用していますか?どのオーバーロードされた関数が呼び出されているかを調べる方法は?

  2. 一般に、関数定義と関数呼び出しの間の引数の数と型が完全に一致しない場合、どのオーバーロードされた関数定義を使用するかを決定する方法はありますか?

+1

私はあなたが意味すると思う: 'float float1 = 1.2;'と 'float float2 = 1.4;' – Mysticial

+0

私のまっすぐな答えは 'int - > float'は' float - > int'よりも優れた変換です。興味深いことに、これが記載されている標準で見積もりが見つかりませんでした。 –

+0

あなたはどのコンパイラ/バージョンを使用していますか?標準を検証した後、 'f(int1、float2)'が* ambiguous *であるため、コードでエラーが発生するはずです。 GCCとClangは同意します。 –

答えて

4

標準で決定した後に、1つのオーバーロードが他のオーバーロードよりも優先されるべきであると判断した後、それは避けるべきであるという結論に至りました。f(int1, float2)の場合、オーバーロードは、コンパイルしないでください。あなたのコンパイラがそれを受け入れるなら、実装にバグがあるかもしれません。 2番目の質問のよう

、標準関数への呼び出しを一致させるために使用することができる変換を定義し、それはまた、より良好変換と呼ばれる(部分的な順序として機能するもの変換にランクを定義)。コンパイラは常にの変換を選択します。変換があり、が最良の場合は、の変換が行われます。異なるコンパイラとコードの曖昧さの

検証:

GCC:

conv.cpp:22: error: call of overloaded ‘f(int&, float&)’ is ambiguous 
conv.cpp:5: note: candidates are: float f(int, int) 
conv.cpp:9: note:     float f(float, float) 

打ち鳴らす:

conv.cpp:22:13: error: call to 'f' is ambiguous 
    cout << f(int1, float2) << endl; // output: 2 
      ^
conv.cpp:5:7: note: candidate function 
float f (int a, int b) { 
    ^
conv.cpp:9:7: note: candidate function 
float f (float a, float b) { 
    ^

MSVS 2010(XEOのおかげで):

error C2666: 'f' : 2 overloads have similar conversions 
      src\main.cpp(2): could be 'void f(int,int)' 
      src\main.cpp(1): or  'void f(float,float)' 
      while trying to match the argument list '(int, float)' 
+0

+1、MSVC10をコードを拒否するコンパイラに追加することができます。[ここにエラーメッセージがあります](http://ideone.com/juukz)。 – Xeo

0

あなたが知る必要があるすべてとより:http://www.learncpp.com/cpp-tutorial/76-function-overloading/

完全に一致は可能ではないと昇進によって一致が可能でない場合は基本的に二つ目は、理由は最初のパラメータの変換によるマッチを(選択されていますintからfloatまで)が行われます。

+0

ここで問題となるのは、標準では 'int-> float'変換が' float-> int'変換よりも優れた変換シーケンスとみなされます。両方とも浮動整数変換* –

+0

float-> intあなたが情報を失うので、より良いと考えられています。 – Tudor

+0

我々はそれに同意します:潜在的に情報を失うかもしれない変換をより良く考えることは理にかなっていませんが、おそらく私が見つけることができなかった標準のどこかで定義されています。 –

0

intfloatに変換すると、情報がなくなります。 floatintに変換すると、数値の小数部分が失われます。コンパイラが正確な過負荷マッチを見つけることができない場合、コンパイラは情報の損失が最も少ないものを選択します。

関連する問題