名前のルックアップの過負荷解像度/あいまいさ(どちら)
-
29-09-2019 - |
質問
$ 7.3.3/14(C ++ 03)
struct A { int x(); };
struct B : A { };
struct C : A {
using A::x;
int x(int);
};
struct D : B, C {
using C::x;
int x(double);
};
int f(D* d) {
return d->x(); // ambiguous: B::x or C::x
}
「f」のコードのコメントは、「b :: x」または「c :: x」の間のあいまいさを期待できることを示しています。
ただし、G ++(IDEONE)またはComeauをコンパイルすると、エラーはわずかに異なります。 b :: xまたはc :: xのあいまいさを示す代わりに、これらのエラーは、AがDの曖昧な基盤であるという事実を示しています
prog.cpp:infunction 'int f(d*)':prog.cpp:16:error: 'a'は 'd'の曖昧な基盤です
と
「comeautest.c」、行21:エラー:ベースクラス "a"はあいまいなリターンd-> x()です。 //あいまいな:b :: xまたはc :: x
$ 10.2で名前のルールルールを使用すると、コードスニペットのコメントが実際には正しくないと感じています。エラーは、実際には何よりも、他の何よりも基本クラス「A」のあいまいさに関連しています(たとえば、過負荷解像度のあいまいさ)。何かご意見は?
解決
これは、C ++ 03の名前の見た目のひねりによって引き起こされます。明確なサブオブジェクトのチェックは、C ++ 03のクラスメンバー名検索の一部でした。 C ++ 03のルックアップでは、d :: xおよびc :: xとa :: xを見つけます。ここで、a :: xはタイプAの2つの異なるサブオブジェクトに関連付けられています。
C ++ 0xでは、明確なサブオブジェクトのチェックがそれぞれのサブクローゼの一部になりました。 DR#39: :クラス場所 x
直接のメンバーは曖昧なベースです。したがって、条項5は、条項10ではなくコンパイルエラーを引き起こします。
コメントはのサブオブジェクトについて語っていることに注意してください A
. 。の1つのサブオブジェクトがあります A
それは道を通り過ぎます B
, 、およびの別のサブオブジェクト A
それは道を通り過ぎます C
. 。これがコメントが言う理由です。B::x
また C::x
"。同じクラスタイプの複数のサブオブジェクトの存在は、アクセシビリティの問題を無視してクラスタイプに変換しようとするだけで決定できます。変換が曖昧な場合、サブオブジェクトは複数回表示されました。
他のヒント
Clang ++は、G ++とComeauによって生成されたエラーの組み合わせをいくらか与えます
C:\Users\SUPER USER\Desktop>clang++ chubsdad.cpp
chubsdad.cpp(12) : error: ambiguous conversion from derived class 'D' to base class
'A':
struct D -> struct B -> struct A
struct D -> struct C -> struct A
return d->x(); // ambiguous: B::x or C::x
^
1 error generated.