Curiously recurring template pattern: Difference between revisions

Content deleted Content added
Monkbot (talk | contribs)
m Task 16: replaced (3×) / removed (0×) deprecated |dead-url= and |deadurl= with |url-status=;
Line 3:
==History==
The technique was formalized in 1989 as "''F''-bounded quantification."<ref>{{cite web|url=http://staff.ustc.edu.cn/~xyfeng/teaching/FOPL/lectureNotes/CookFBound89.pdf|title=F-Bounded Polymorphism for Object-Oriented Programming|author=William Cook|date=1989|display-authors=etal}}</ref> The name "CRTP" was independently coined by [[Jim Coplien]] in 1995,<ref>{{cite journal | author=Coplien, James O. | title=Curiously Recurring Template Patterns | journal=C++ Report | year=February 1995 | pages=24–27 | url=http://sites.google.com/a/gertrudandcope.com/info/Publications/InheritedTemplate.pdf}}</ref> who had observed it in some of the earliest [[C++]] template code
as well as in code examples that [[Timothy Budd]] created in his multiparadigm language Leda.<ref>{{cite book | first=Timothy | last=Budd | authorlink=Timothy Budd | title=[[Multiparadigm programming in Leda]] | publisher=Addison-Wesley | isbn=0-201-82080-3 | year=1994}}</ref> It is sometimes called "Upside-Down Inheritance"<ref>{{Cite web|url=http://www.apostate.com/programming/atlupsidedown.html |title=Apostate Café: ATL and Upside-Down Inheritance |date=2006-03-15 |access-date=2016-10-09 |deadurlurl-status=bot: unknown |archiveurl=https://web.archive.org/web/20060315072824/http://www.apostate.com/programming/atlupsidedown.html |archivedate=15 March 2006 |df=dmy }}</ref><ref>{{Cite web|url=http://archive.devx.com/free/mgznarch/vcdj/1999/julmag99/atlinherit1.asp |title=ATL and Upside-Down Inheritance |date=2003-06-04 |access-date=2016-10-09 |deadurlurl-status=bot: unknown |archiveurl=https://web.archive.org/web/20030604104137/http://archive.devx.com/free/mgznarch/vcdj/1999/julmag99/atlinherit1.asp |archivedate=4 June 2003 |df=dmy }}</ref> due to the way it allows class hierarchies to be extended by substituting different base classes.
 
The Microsoft Implementation of CRTP in [[Active Template Library]] (ATL) was independently discovered, also in 1995 by Jan Falkin who accidentally derived a base class from a derived class. Christian Beaumont first saw Jan's code and initially thought it couldn't possibly compile in the Microsoft compiler available at the time. Following this revelation that it did indeed work, Christian based the entire ATL and [[Windows Template Library]] (WTL) design on this mistake.{{Citation needed|date=August 2018}}
Line 57:
In the above example, note in particular that the function Base<Derived>::interface(), though ''declared'' before the existence of the struct Derived is known by the compiler (i.e., before Derived is declared), is not actually ''instantiated'' by the compiler until it is actually ''called'' by some later code which occurs ''after'' the declaration of Derived (not shown in the above example), so that at the time the function "implementation" is instantiated, the declaration of Derived::implementation() is known.
 
This technique achieves a similar effect to the use of [[virtual function]]s, without the costs (and some flexibility) of [[dynamic polymorphism]]. This particular use of the CRTP has been called "simulated dynamic binding" by some.<ref>{{cite web | url=http://www.pnotepad.org/devlog/archives/000083.html | title=Simulated Dynamic Binding | date=7 May 2003 | accessdate=13 January 2012 | deadurlurl-status=yesdead | archiveurl=https://web.archive.org/web/20120209045146/http://www.pnotepad.org/devlog/archives/000083.html | archivedate=9 February 2012 | df=dmy-all }}</ref> This pattern is used extensively in the Windows [[Active Template Library|ATL]] and [[WTL]] libraries.
 
To elaborate on the above example, consider a base class with '''no virtual functions'''. Whenever the base class calls another member function, it will always call its own base class functions. When we derive a class from this base class, we inherit all the member variables and member functions that weren't overridden (no constructors or destructors). If the derived class calls an inherited function which then calls another member function, that function will never call any derived or overridden member functions in the derived class.