I'm trying to understand if a simple CRTP pattern is valid by the standard.
The code below compiles and works as expected (on clang).
But my understanding of the relevant standard chapters/paragraphs is that the point of instantiation of the virtual function CRTP< Derived, Base >::DoSomething() should be at point (B) of the code, where the full declaration of Derived is not available. Therefore the inner typedef Type should not be available either.
Can anyone kindly point out the relevant standard chapter that validates this code?
In other words, something that says that in this case the virtual function is instantiated ATFER point C? Thanks a lot in advance for any insight.
Francesco
//-------------------------
// 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
//-------------------------
Relevant (?) standard paragraphs:
14.6.4.1 4 If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization.
14.7.1 4 A class template specialization is implicitly instantiated if the class type is used in a context that requires a completely-defined object type or if the completeness of the class type might affect the semantics of the program.
14.7.1 9 An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instan- tiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.