8

次のコードで次のエラーが発生する理由を教えてください - call of overloaded "C(int)" is ambiguous

C(char x) はプライベートなので、外部からは C(float) ctor のみが表示され、int を float に変換して呼び出す必要があると思います。

しかし、そうではありません。

class C
{
    C(char  x)
    {
    }
public:
    C(float t)
    {
    }
};

int main()
{
    C p(0);
}
4

3 に答える 3

19

これについては、Scott Meyer による「Effective C++」で説明されています。これがあいまいである理由は、メンバーの可視性を単に変更しても、他の場所にある既存のコードの意味が変わらないようにしたかったからです。

それ以外の場合は、C クラスがどこかのヘッダーにあるとします。プライベート C(int) メンバーがある場合、提示するコードは C(float) を呼び出します。何らかの理由で C(int) メンバーが公開された場合、古いコードもそれが呼び出す関数も変更されていないにもかかわらず、古いコードは突然そのメンバーを呼び出します。

編集:その他の理由:

さらに悪いことに、次の 2 つの関数があるとします。

C A::foo() 
{
    return C(1.0);
}

C B::bar() 
{
    return C(1.0);
}

これら 2 つの関数は、foo または bar が C のフレンドとして宣言されているかどうか、または A または B がそれを継承しているかどうかに応じて、異なる関数を呼び出すことができます。同じコードで異なる関数を呼び出すのは恐ろしいことです。

(これはおそらく Scott Meyer の議論ほど適切ではありませんが、それがアイデアです。)

于 2009-03-13T20:18:38.457 に答える
7

0 はintタイプです。float または char のいずれかに等しく暗黙的にキャストできるため、呼び出しはあいまいです。可視性は、これらの目的には関係ありません。

0.00.、またはを配置するか0.0fC(char)コンストラクターを完全に削除します。

編集:標準の関連部分、セクション13.3:

3) [...] ただし、候補関数と引数リストが識別されると、最適な関数の選択はすべての場合で同じになります。

  • 最初に、候補関数のサブセット (適切な数の引数を持ち、特定の他の条件を満たす関数) が選択され、実行可能な関数のセットが形成されます (13.3.2)。
  • 次に、各引数を実行可能な各関数の対応するパラメーターに一致させるために必要な暗黙的な変換シーケンス (13.3.3.1) に基づいて、実行可能な最適な関数が選択されます。

4) 実行可能な最適な関数が存在し、一意である場合、オーバーロードの解決は成功し、結果としてそれが生成されます。そうしないと、オーバーロードの解決が失敗し、呼び出しの形式が正しくありません。オーバーロードの解決が成功し、実行可能な最適な関数が使用されているコンテキストでアクセスできない場合 (第 11 節)、プログラムは不適切な形式です。

可視性は選択プロセスの一部ではないことに注意してください。

于 2009-03-13T20:18:41.720 に答える
-1

私はそうは思わない:

C p(0);

に変換されています:

C(float t)

あなたはおそらくする必要があります:

C p(0.0f);
于 2009-03-13T20:19:39.533 に答える