単純な CRTP パターンが標準で有効かどうかを理解しようとしています。
以下のコードはコンパイルされ、(clang で) 期待どおりに動作します。
しかし、関連する標準の章/段落についての私の理解では、仮想関数 CRTP< Derived, Base >::DoSomething() のインスタンス化のポイントは、コードのポイント (B) にある必要があります。ここでは、Derived の完全な宣言はありません。利用可能。したがって、内側の typedef Type も使用できないはずです。
このコードを検証する関連する標準の章を誰か親切に指摘できますか?
つまり、この場合、仮想関数がインスタンス化された ATFER ポイント C であるということですか? 洞察をお寄せいただきありがとうございます。
フランチェスコ
//-------------------------
// START CODE
#include <iostream>
struct Type1 {};
struct Type2 {};
struct Base
{
virtual ~Base() {}
virtual void DoSomething() = 0;
};
template< typename T, typename U >
struct CRTP : U
{
virtual void DoSomething() { DoSomething( typename T::Type() ); }
void DoSomething( Type1 ) { std::cout << "1\n"; }
void DoSomething( Type2 ) { std::cout << "2\n"; }
};
// (A) point of inst. of CRTP< Derived, Base > ( 14.7.1.4 ) ??
// (B) point of inst. of CRTP< Derived, Base >::DoSomething() (14.6.4.1.4 ) ??
struct Derived : CRTP< Derived, Base >
{
typedef Type2 Type;
};
// (C)
int main()
{
Base * ptr = new Derived;
ptr->DoSomething();
delete ptr;
}
// END CODE
//-------------------------
関連する (?) 標準段落:
14.6.4.1 4 仮想関数が暗黙的にインスタンス化される場合、そのインスタンス化のポイントは、それを囲むクラス テンプレートの特殊化のインスタンス化のポイントの直後です。
14.7.1 4 クラス型が完全に定義されたオブジェクト型を必要とするコンテキストで使用される場合、またはクラス型の完全性がプログラムのセマンティクスに影響を与える可能性がある場合、クラス テンプレートの特殊化は暗黙的にインスタンス化されます。
14.7.1 9 実装は、関数テンプレート、メンバー テンプレート、非仮想メンバー関数、メンバー クラス、またはインスタンス化を必要としないクラス テンプレートの静的データ メンバーを暗黙的にインスタンス化してはなりません。仮想メンバー関数がインスタンス化されない場合、実装がクラス テンプレートの仮想メンバー関数を暗黙的にインスタンス化するかどうかは指定されていません。