//+------------------------------------------------------------------+ //| TemplatesExtended.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| External declarations in templates | //+------------------------------------------------------------------+ template class ClassType { ClassType() // private ctor, used only once in the 'create' method { s = &this; } static ClassType *s; // pointer to existing object public: static ClassType *create() // hard init (ensure object is created) { static ClassType single; // local static: singleton per T return &single; } static ClassType *check() // soft init (return existing pointer w/o creation) { return s; } template void method(const U &u); }; template template void ClassType::method(const U &u) { Print(__FUNCSIG__, " ", typename(T), " ", typename(U)); } template static ClassType * ClassType::s = NULL; //+------------------------------------------------------------------+ //| Inheritance with templates | //+------------------------------------------------------------------+ #define RTTI Print(typename(this)) template class DerivedFrom { typedef void(*ppp)(T*); static void constraints(T* p) { B* pb = p; } public: DerivedFrom() { ppp p = constraints; } }; class Base { public: Base() { RTTI; } }; template class Derived : public T { public: Derived() { RTTI; } }; template class Base1 { Derived object; public: Base1() { RTTI; } }; template // full "specialization" class Derived1 : public Base1 // (1 of 1 parameter specified) { DerivedFrom df(); // constraint: want T based on Base public: Derived1() { RTTI; } }; template class Base2 : public T { public: Base2() { RTTI; E e = (E)""; } // constraint: stringifiable E expected }; template // partial "specialization" class Derived2 : public Base2 // (1 of 2 parameters specified) { public: Derived2() { RTTI; } }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ClassType *object = ClassType::create(); double d = 5.0; object.method(d); // OUTPUT: // void ClassType::method(const double&) string double Print(ClassType::check()); // 1048576 (example of instance id) Print(ClassType::check()); // 0 (no instance for T=long) Derived2> derived2; // OUTPUT: // Base // Derived // Base1 // Derived1 // Base2,string> // Derived2> } //+------------------------------------------------------------------+