13

オーバーロード中に、コンパイラは仮引数が同じ型であるかどうかをチェックすると思いました。例えば:

void a(int x)
void a(double x)

2 つの "x" の型が異なるため、単純にオーバーロードできます。

しかし、次の二つは型が違うのでしょうか?

void f(int y)
void f(int& y)

1 つは PBV で、もう 1 つは PBR であることを理解しています。しかし、2番目のyも「int」型ですよね?正常にコンパイルされるのはなぜですか?

PSコンパイルはできますが、実行されず、あいまいな実行時エラーが報告されることに気付きました。

4

4 に答える 4

8

大まかに言えば、関数は以下に基づいてオーバーロードできます。

  • 引数の数
  • 引数のタイプ
  • 引数のシーケンス

この例は、2 番目の基準を満たしているため、コンパイルされます。
intint &は異なるデータ型です。


次の例を検討してください。

void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
     return 0;
}  

上記のコードは有効なコードであるため、コンパイルされます。関数に渡される関数引数に応じて、コンパイラは関数呼び出しに最適な一致を検出する場合と検出しない場合があります。そのため、関数自体は共存できますが、特定の方法で使用すると、コンパイラにあいまいさが生じる可能性があります。

例: 次のコードでは、リテラルを非 const 参照にバインドすることはできないため、関数呼び出しの唯一の候補は非参照バージョンであり、これはコンパイルして問題なく動作するはずです。

void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
    foo(20); 
    return 0;
}  

しかし、

void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
    int i = 10;
    foo(i);
    return 0;
}  

上記は、コンパイラが 2 つの関数呼び出し間の最適な一致を検出できないため、コンパイラにあいまいさを引き起こします。

于 2012-12-10T10:19:04.677 に答える
2

場合によります。コードからこれらの関数を呼び出さない場合、コンパイラはそれらを最適化して除外する可能性があります。そうでない場合は、テキスト ビューアーで .obj ファイルを開き、関数名を検索できます (f例: floop:-) よりも一意の名前を付けます)。

しかし、実際に使用してみると、違いに気付くでしょう。電話すれば

f(5);

f(int y)参照によって定数を渡すことは不可能であるため、コンパイラはバージョンのみを使用できます。しかし、もしそうなら

int b = 10;
f(b);

fどちらの形式もこの方法で呼び出すことができるため、コンパイラはあいまいなエラーを発行します。

于 2012-12-10T10:27:02.597 に答える
2

Firstly, ambiguety is ALWAYS reported at compile time.

Secondly, whether your example compiles or not depends on how you use this function

void f(int y)
{
}
void f(int& y)
{
}


int main ()
{
    int a = 10;

    f (a); // ERROR: ambiguous call
    f (10); // OK
}

In the first case there is an error, becasue a can be passed as both copy and reference. In the second case there will be no error, because int literal cannot be passed by non-const reference

于 2012-12-10T10:26:57.313 に答える
2

x が int である f(x) を呼び出してみましょう。

$13.3.3.1.4 - 「参照型のパラメーターが引数式に直接バインドされる場合 (8.5.3)、引数式がパラメーター型の派生クラスである型を持っていない限り、暗黙的な変換シーケンスは恒等変換です。 、この場合、暗黙の変換シーケンスは派生からベースへの変換です"

したがって、f(int &) は完全一致であり、f(int) も同一性変換であるため、完全一致です。したがって、あいまいさ

'f(2)' を呼び出してみましょう

右辺値は非定数左辺値にバインドされないため、「f(int &)」はまったく一致しないため、これは問題ありません。したがって、あいまいさはありません

したがって、標準では、'f(T)' と 'f(T &)' がオーバーロード セットを形成することを許可しています。

于 2012-12-10T10:30:30.580 に答える