次のコードは、clang と gcc の両方で拒否されます
template<typename T>
void f(T t)
{
t.Dependent::f(); // clang accepts, gcc rejects
t.operator Dependent*(); // both reject
}
struct Dependent
{
void f();
};
struct A : Dependent
{
operator Dependent*();
};
template void f<A>(A);
私が標準を読んだところ、両方の表現が受け入れられるべきであることが示唆されました。
どちらの場合もDependent
、型名のみを指定できます。
どちらの場合も、名前Dependent
は「オブジェクト式のクラスで検索」されますt
。t
型に依存する式と同様に、テンプレートがインスタンス化されるまでルックアップを延期する必要があります。
足りないものはありますか?
編集: そのような名前が依存していないことが意図されている場合、この決定の根拠は何ですか? t.operator X::Dependent*
名前空間または型名のt.X::Dependent::f
ような構造体の評価を延期する必要がなければ、実装者の生活が楽になることがわかります。X
これが現在の文言の意図的な副作用なのか意図しない副作用なのかははっきりしません。
C++ Working Draft N3337 からの関連引用:
3.4.5 クラスメンバーアクセス [basic.lookup.classref]
クラス メンバー アクセスの id-expression が、クラス名または名前空間名::... の形式の修飾 ID である場合、. の後にクラス名または名前空間名が続きます。or -> 演算子は最初にオブジェクト式のクラスで検索され、見つかった場合はその名前が使用されます。それ以外の場合は、postfix-expression 全体のコンテキストで検索されます。[注: 3.4.3 を参照してください。これは :: の前の名前の検索について説明しています。これは型または名前空間の名前のみを検索します。—終わりのメモ]
id-expression が conversion-function-id の場合、最初にその conversion-type-id がオブジェクト式のクラスで検索され、見つかった場合はその名前が使用されます。それ以外の場合は、postfix-expression 全体のコンテキストで検索されます。これらの各ルックアップでは、型を表す名前、または特殊化が型であるテンプレートのみが考慮されます。
14.6.2 依存名 [temp.dep]
テンプレート内では、インスタンス化ごとに異なるセマンティクスを持つ一部の構成要素があります。このような構成は、テンプレート パラメーターに依存します。特に、型と式は、(テンプレート引数によって決定される) テンプレート パラメーターの型および/または値に依存する場合があり、これにより、特定の名前の名前検索のコンテキストが決定されます。式は、型依存 (テンプレート パラメーターの型) または値依存 (非型テンプレート パラメーターの値) の場合があります。
[...]
そのような名前はバインドされておらず、テンプレート定義のコンテキストとインスタンス化のポイントのコンテキストの両方で、テンプレートのインスタンス化のポイント (14.6.4.1) で検索されます。
14.6.2.1 依存型 [temp.dep.type]
名前は、不明な専門分野のメンバーです。
[...]
—クラス メンバー アクセス式(5.2.5)のメンバーを示す ID 式。
— オブジェクト式の型が現在のインスタンス化であり、現在のインスタンス化に少なくとも 1 つの依存基底クラスがあり、id-expression の名前検索で現在のインスタンス化のメンバーまたはその非依存基底クラスが見つからない。また
—オブジェクト式の型は依存型であり、現在のインスタンス化ではありません。
[...]
ある場合、型は従属です。
—未知の専門分野のメンバー、