11

次のコードは、エラーなしでコンパイルできます。

template <typename T> struct A {
    void f() { this->whatever; } // whatever is not declared before
};
int main() {
    A<int> a;
}

そして、それthisは型に依存する式であるためwhatever、実際のテンプレート引数が判明するまで名前の検索が延期されるためであることはわかっています。この場合、メンバー関数f()は使用されないため、 のインスタンス化はA<T>::f存在せず、 の名前検索whateverは実行されません。

thisクラステンプレートに次のようなタイプ依存のベースがある場合、それはタイプ依存であることを理解できます。

template <typename T> struct B { T whatever; };
template <typename T> struct A : B<T> {
    void f() { this->whatever; }
};
int main() {
    A<int> a;
}

テンプレート クラス の定義を解析するとき、そのベースの型を知るAことは不可能です。それどころか、メンバー関数がどこかで使用されるとすぐに、最初の例で合法になる可能性は見当たりません。this->whateverB<T>whateverthis->whateverf

this->whateverでは、最初の例のいくつかの点で合法である可能性はありますか? thisそうでない場合、その場合に型依存の式として扱われるべき他の理由はありますか?

4

3 に答える 3

4

の有効な特殊化がないため、コードは「形式が正しくなく、診断は不要」ですA::f。実際、仕様ではthis->whatever、未知の特殊化のメンバーでも (依存する基本クラスがないため)、現在のインスタンス化のメンバーでもない (非依存の基本クラスでもクラス テンプレートでも宣言されていないため) と述べています。自体)。さらに、これによりコードが無効になり、診断は必要ありません (ただし許可されます)。これについては、 https://stackoverflow.com/a/17579889/34509で詳細に説明されています。

thisテンプレート パラメーターの値がまだ定義に含まれていないため、型に依存します。たとえば、すぐに解決することはできませんが、のクラス テンプレートがインスタンス化さSomeOtherTemplate<decltype(*this)>れるまで待機する必要があります (そのため、 beforeが必要です)。thistypenameSomeOtherTemplate<decltype(*this)>::type

ただし、this型に依存しているからといって、それも同様であるとは限りませんthis->whatever。前述のように、仕様にはこれを無効として正しく分類するためのツールがあり、実際には型に依存することもありません。this->whateverそれは言う

クラス メンバー アクセス式 ([expr.ref]) は、式が現在のインスタンス化のメンバーを参照し、参照されるメンバーの型が依存している場合、またはクラス メンバー アクセス式が未知のメンバーを参照している場合、型に依存します。専門。

于 2016-08-30T06:47:17.143 に答える