The "Curiously Recurring Template" pattern comes from an article by JimCoplien: "The Column Without a Name: A Curiously Recurring Template Pattern," CppReport, February 1995.
It occurs where a BaseClass is templated on the type of its derived class:
template<typename T> class Base; class Derived: public Base<Derived>;Such a base class has the following interesting properties:
Why would you want to use it? CRT classes are almost always used to factor out functionality that is similar for several classes but which needs to be partially specialized for those classes. Here are some examples:
JimCoplien has made available the original paper here: https://sites.google.com/a/gertrudandcope.com/info/Publications/InheritedTemplate?.pdf?attredirects=0
Base class that implements the infix operators for an arithmetic type in terms of +=, -=, *=, and /=:
template<typename T> struct ArithmeticType { T operator + (const T& other) const { T result(*this); result += other; return result; } // etc. }; class Quaternion: public ArithmeticType<Quaternion> { Quaternion& operator += (const Quaternion& other) { // etc. } };
COM-like RunTimeTypeInformation implementation helper:
struct Null { }; template <typename A, typename B> struct TypeList { typedef A head; typedef B rest; }; template<typename TL> struct Inherits: public TL::head, public Inherits<TL::rest> { }; template<> struct Inherits<Null> { }; template<typename C, typename TL> struct InterfaceFinder { static void* GetInterface(C* obj, const GUID& iid) { if (iid == TL::head::GetUuid()) return static_cast<typename TL::head*>(obj); return InterfaceFinder<C, typename TL::rest>::GetInterface(obj, iid); } }; template<typename C> struct InterfaceFinder<C, Null> { static void* GetInterface(C* obj, const GUID& iid) { return 0; } }; template<typename D, typename ITL> struct Implements: public Inherits<ITL> { void *QueryInterface(const GUID& iid) { return InterfaceFinder<D, ITL>::GetInterface(static_cast<D*>(this), iid); } template<typename Intf> bool QueryInterface(Intf*& result) { result = QueryInterface(Intf::GetUuid()); return (result != 0); } }; class Example: public Implements< Example, TypeList<FirstInterface, TypeList<SecondInterface, Null> > > { }; // ... Example* object; FirstInterface* first; if(object->QueryInterface(first)) first->foo();(Okay, the syntax is a little awkward, but this could be radically improved with a suitable macro for creating typelists, c.f. AndreiAlexandrescu's work on the subject, described in ModernCeePlusPlusDesign.)
Counting the number of instances of a class:
template<typename T> class Counter { public: Counter() { ++count; } Counter(const Counter&) { ++count; } ~Counter() { --count; } static size_t howMany() { return count; } private: static size_t count; }; template<typename T> size_t Counter<T>::count = 0; // either embed a Counter to count objects class Widget { public: ..... static size_t howMany() { return Counter<Widget>::howMany(); } private: ..... Counter<Widget> c; }; // or inherit from Counter to count objects class Widget: private Counter<Widget> { public: ..... using Counter<Widget>::howMany; // make howMany public };from ScottMeyers, "Counting Objects in C++," C/C++ Users Journal, April 1998 (http://www.ddj.com/cpp/184403484).
Isn't this similar to MixIns in other languages? Basically, "given that type (a) implements interface (x), derive it into type (b) that implements interface (y) using the template code below". Your example above looks similar to corresponding RubyLanguage examples.
Yes, the infix operators example is a Ruby mixin, especially when you consider that the ArithmeticType template is publicly inherited. The COM-like helper example I don't understand. The instance counter example can be done with difficulty in RubyLanguage by screwing around with Module#class_eval, but that's not necessary. Instead, in idiomatic Ruby, instance counts are reported with ObjectSpace.each_object(Widget) {}. But beginning with version 1.1, ObjectSpace#each_object will be disabled by default in JayRuby for performance reasons (http://www.ruby-forum.com/topic/129606). -- ElizabethWiethoff
Is this the same as UpsideDownInheritance as used by the WindowsTemplateLibrary? I'm guessing "yes", since its basis, the ActiveTemplateLibrary, is referenced below.
A similar idiom is used in JavaLanguage, but not often because Java generics are so limited.
public class Base<T> { public T m() { ... } } public class Derived extends Base<Derived> { ... }
EiffelLanguage lets you use refer to the type of the derived class in the base class, so you don't need this idiom.
See GenerativeProgrammingBook; this idiom shows up a lot.
Also described in Rector, Sells, ATL Internals (ISBN 0201695898 ) as "Simulating DynamicBinding". See SimulatedDynamicBinding.
Also described in Eckel, Allison, ThinkingInCeePlusPlus, vol. 2, ch. 5.