3

ここで何が起こっているのかわかりません

class A{};
class B : A {};

void func(A&, bool){}
void func(B&, double){}

int main(void)
{
    B b;
    A a;
    bool bo;
    double d;

    func(b, bo);
}

コンパイル時に、Visual2010はこのエラーをオンラインで表示しますfunc(b, bo);

2 overloads have similar conversions
could be 'void func(B &,double)'
or       'void func(A &,bool)'
while trying to match the argument list '(B, bool)'

boolパラメーターが過負荷を解決するのに十分でない理由がわかりません。私はこの質問を見てきました、そして受け入れられた答えで指摘されているように、boolはboolの過負荷を好むはずです。私の場合、最初のパラメーターでは適切な関数を選択するのに十分ではないことがわかりますが、2番目のパラメーターがあいまいさを解決しないのはなぜですか?

4

2 に答える 2

5

オーバーロードルールは、想像よりも少し複雑です。各引数を個別に見て、その引数に最適なものを選択します。次に、すべての引数に最適なオーバーロードが1つだけある場合、それが呼び出されます。この例では、最初の引数に最適なのは、の2番目のバージョンですfunc。これは、への変換のみが必要なためBですB&。他のバージョンでは、に変換してからに変換するfunc必要があります。2番目の引数については、最初のバージョンのBB&B&A&func変換を必要としないため、が最適です。最初のバージョンは2番目の引数に最もよく一致しますが、最初の引数に最もよく一致しないため、考慮されません。同様に、2番目のバージョンは最初の引数に最適ですが、2番目の引数に最適ではないため、考慮されません。現在、残っているバージョンはなくfunc、呼び出しは失敗します。

于 2012-08-23T15:42:05.687 に答える
2

過負荷解決ルールは、PeteBeckerが書いたものよりもさらに複雑です。のオーバーロードごとfに、コンパイラーは変換が必要なパラメーターの数だけでなく、変換のランクもカウントします。

ランク1

変換は必要ありません

左辺値から右辺値への変換

配列からポインタへの変換

関数からポインタへの変換

資格変換

ランク2

インテグラルプロモーション

浮動小数点プロモーション

ランク3

積分変換

浮動小数点変換

浮動積分変換

ポインタ変換

メンバーへのポインタの変換

ブール変換

すべての候補が非テンプレート関数であると仮定すると、他の候補の同じパラメーターのランクよりもランクが高く、他のパラメーターのランクが悪くないパラメーターがある場合にのみ、関数が勝ちます。

それでは、OPのケースを見てみましょう。

  • func(A&, bool):1番目のパラメーターの変換B&-> A&(ランク3)、2番目のパラメーターの完全一致(ランク1)。
  • func(B&, double):1番目のパラメーターの完全一致(ランク1)bool->double、2番目のパラメーターの変換(ランク3)。

結論:誰も勝ちません。

于 2012-08-23T15:54:46.627 に答える