私は、これらのいずれもが不適切であるとは思わない。まず、 forusing X::f2
がX
検索され、これにより明確にクラス type が生成されX
ます。次にf2
inX
が検索され、これも明確です ( in D
! では検索されません)。
2 番目のケースも同じ理由で機能します。
ただし、オブジェクトを呼び出す 場合、名前はtypeのすべてのサブオブジェクトで検索され、そのようなサブオブジェクトが 2 つあり、非静的メンバー関数であるため、呼び出しがあいまいになります。同じ理由が 2 番目のケースにも当てはまります。直接または使用して名前を付けるかどうかは、これに違いはありません。これらはどちらもクラスを指定します。f2
D
f2
D
X
D
f2
f3
Z::X
X
X
using 宣言のあいまいさを得るには、別の方法で記述する必要があります。C++0xusing ThisClass::...;
では無効であることに注意してください。ただし、名前全体が基本クラスのメンバーを参照している限り、これは C++03 にあります。
逆に、これが C++0x で許可される場合は、using 宣言全体も有効になります。これは、C++0x が名前検索でサブオブジェクトを考慮しないためです。D::f2
明確に 1 つの宣言( の 1 つX
) のみを参照します。DR #39と最終論文N1626を参照してください。
struct D : Y, Z{
// ambiguous: f2 is declared in X, and X is a an ambiguous base class
using D::f2;
// still fine (if not referred to by calls/etc) :)
using Z::X::f3;
};
struct E : D {
// ambiguous in C++03
// fine in C++0x (if not referred to by an object-context (such as a call)).
using D::f2;
};
C++03 標準では、段落10.2
およびでこれについて説明してい3.4.3.1
ます。
Edit3 の応答:
はい、GCC と VS2010 は間違っています。trouble
は、 の注入されたクラス名によって検出された型と、::trouble
として検出されたネストされたクラスを参照しY::trouble
ます。の前の名前は、オブジェクト、関数、および列挙子の名前を無視して (最初の箇条書きでにtrouble
委譲する::
によって) 非修飾ルックアップを使用して検索されます (ただし、この場合、そのような名前はありません)。次に、次の要件に違反します。3.4.1/7
10.2
3.4.3/1
10.2
結果として得られる宣言のセットがすべて同じ型のサブオブジェクトからのものではない場合...プログラムの形式が正しくありません。
VS2010 と GCC が C++0x の文言をコモーとは異なる方法で解釈し、その文言をさかのぼって実装する可能性があります。
メンバー宣言として使用される using 宣言では、nested-name-specifier は、定義されているクラスの基本クラスに名前を付けるものとします。
これは、非基底クラスが考慮されることを意味しますが、非基底クラスが指定されている場合はエラーになります。標準が非基本クラス名を無視するつもりなら、can only here と言うか、明示的に綴ります (両方のプラクティスが行われます)。ただし、この標準は、 shouldおよびcanの使用とはまったく関係ありません。また、GCC は C++0x の文言を実装しています。これは、using 宣言にそのクラス名が含まれているという理由だけで、それ以外の場合は完全に問題のない C++03 コードを拒否するためです。
不明確な表現の例として、次の表現を考えてみましょう。
a.~A();
がクラス オブジェクトの場合はメンバー関数呼び出しになる可能性がありますが、スカラー型 ( などa
) の場合は疑似デストラクタ呼び出し (ノーオペレーション) になる可能性があるため、これは構文的にあいまいです。しかし、標準が述べているのは、疑似デストラクタ呼び出しの構文と、それぞれ および でのクラス メンバー アクセスに関するものです。a
int
5.2.4
5.2.5
ドット演算子の左辺はスカラー型でなければなりません。
最初のオプション (ドット) の場合、最初の式 (オブジェクト式) の型は「クラス オブジェクト」(完全な型) になります。
あいまいさがまったく解消されないため、これは間違った使い方です。「can only」を使用する必要があり、コンパイラはそのように解釈します。一部の委員会メンバーが最近usenetで私に言ったように、これには主に歴史的な理由があります。国際規格の構造と起草に関する規則、附属書 Hを参照してください。