Why does *everything* use a template base class in ATL/WTL?

crtp example
c++ template class derived from non-template base class
wtl documentation
c++ template base class polymorphism
crtp template derived class
crtp mixin
crtp multiple inheritance
crtp vs virtual functions

I'm having a lot of trouble understanding the purpose of templates in ATL/WTL code.

When you look at WTL, you see code like:

template <class TBase>
class CEditT : public TBase
{
    ...
};

typedef CEditT<ATL::CWindow> CEdit;
Why is CEditT defined with a template base class?

In other words, in what scenario would CEditT<T> ever be instantiated where T is not CWindow?

It's so that you can override methods in ATL::CWindow that are called by the ATL/WTL class. If there's something that you don't like in ATL::CWindow, you can derive a class from ATL::CWindow with overridden methods, and then pass along your new class as TBase.

For example, ATL::CWindow::CenterWindow for a long while had a bug where it did not properly account for multiple monitors, and I've seen people use this technique to override CenterWindow with a fixed implementation.

Curiously recurring template pattern, The curiously recurring template pattern (CRTP) is an idiom in C++ in which a class X derives This pattern is used extensively in the Windows ATL and WTL libraries. However, if base class member functions use CRTP for all member function calls, the overridden functions in the derived class will be selected at compile  The Active Template Library (ATL) is a set of template-based C++ classes that let you create small, fast Component Object Model (COM) objects. It has special support for key COM features, including stock implementations, dual interfaces, standard COM enumerator interfaces, connection points, tear-off interfaces, and ActiveX controls.

Suppose composition were used instead:

template <class TBase> class CEditT {
public:
  TBase base;
  ...
};

This is not very different from something like:

template <class ITEM> class ListNode {
public:
   ITEM item;
   ListNode<ITEM> *next;
   // ...
};

ListNode could instead inherit ITEM, like CEditT does with TBase, but the drawback would be that then ITEM could not be a basic type like int. On the other hand, a ListNode would then be a kind of ITEM, which could be useful. Furthermore, it would have access to any protected: parts of ITEM.

Modern C++ Programming Cookbook, template. pattern. Polymorphism is the ability to have multiple forms for the same Virtual functions allow derived classes to override implementations from a base class. This technique is used extensively in some libraries, including the Microsoft's Active Template Library (ATL) and Windows Template Library (WTL). The reason for having the class name as a template parameter is so ATL can do the second tricky thing, compile-time virtual function calls. To see this in action, look at this set of classes: template <class T> class B1 { public: void SayHi() { T* pT = static_cast<T*>(this); // HUH?? I'll explain this below pT->PrintClassName(); } void PrintClassName() { cout << "This is B1"; } }; class D1 : public B1<D1> { // No overridden functions at all }; class D2 : public B1<D2> { void PrintClassName

It's so that it can take advantage of the Curiously Recurring Template Pattern. If you create a derived class of CEditT your definition would be class CMyEdit : public CEditT<CMyEdit>. By statically casting its this pointer to your class, CEditT can call your methods without having to use a vtable.

Active Template Library (ATL), ATL is a set of C++ template classes designed to be small, fast, and extensible, These wizards automate some of the tedious plumbing code that all ATL projects must have. ATL provides base classes for implementing COM objects as well as The main reason to use attributes in ATL projects is to make implementing  Active Template Library (ATL) Before we get into using the WTL we'll need to define what the Active Template Library is and its relation to the WTL. The Active Template Library is a set of template classes developed by Microsoft to aid in the development of ActiveX controls and COM objects.

Why does everything use a template base class in ATL/WTL?

In nutshell, to achieve a "weird form of compile-time polymorphism" thanks to a design pattern (rather C++ idiom) one may call "upside-down inheritance" as technique to "specify the base class of a base class" in order to "allows you to insert your own classes into the class hierarchy" to achieve flexibility of specialising types "without hard-coding implementation to any particular derived class".

This all should become clear after reading the excellent article ATL and Upside-Down Inheritance - Understanding ATL's atypical design approach written by Jim Beveridge and published by Visual C++ Developers Journal in July, 1999. Here is link to full not paginated copy of the same article (also in the Wayback Machine).

WTL for MFC Programmers, Part I - ATL GUI Classes, Even if you can read C++ templates without getting a part, the name CMyWnd is defined and can be used in the inheritance list. D1 : public B1<D1> { // No overridden functions at all }; class D2  WLT uses the same mix-in style of programming as ATL, which makes sense given their common heritage and shared classes. Mix-in programming adds a base class to provide a certain set of functionality. The CMainFrame class generated by the WTL wizard is a good example of mix-in programming at work. It has four base classes: CFrameWindowImpl

Windows with C++: Windows Template Library 8.0, WTL extends ATL with a very rich set of class templates for building support for task dialogs via the CTaskDialogImpl base class template. Fortunately, WTL does a good job of wrapping it all up in an easy-to-use set of  If you would like to use the classes in a ATL-but-not-WTL project, you will need to remove all the GUI-thread related sections from the code. The other classes (CThreadT and CThreadImpl) will work with "pure" ATL as well. Conclusion

ATL Internals: Working with ATL 8, Working with ATL 8 Chris Sells, Kirk Fertitta, Christopher Tavares, Brent E. Rector uses _InternalQueryInterface instead of IUnknown::QueryInterface because the list implementation (that is, the CDV template parameter class)—namely, that it Their fundamental purpose is to provide a unique base class instance for  WTL 7.0 and over is designed to support one of ATL::CString or WTL::CString depending on the compile time conditions, some macro definitions, and the inclusion order of the headers; ATL::CString comes with ATL version 7.0; and VC++7.0 and over, eVC, and VCExpress/Platform SDK use ATL 3.0 and do not get it.

wtl/readme.htm - chromium/src/third_party, <p>Welcome to the Windows Template Library, version 10. This document WTL classes can be used with all versions of VC++ from 2005 to the newest, 2019. AppWizard for atlapp.h contains base definitions required for WTL projects. </p>. <p> <li>Visual C++ 2010    (ATL 10.0)</li>. <​li>Visual C++  I'm not very sure how much earlier, because I use many "strange tricks" of VC++), ATL (probably at least 7.0) and it supports the WTL libraries (to compile the AutoSizeScroll you'll need a recent version of WTL.

Comments
  • Maybe to accommodate a case where you want to provide your own Window implementation?
  • @Prætorian: How/why/when would you ever want/need/do that though?
  • No idea :-). Maybe you have some very fancy skin implemented and want all your windows to have that skin. Also, that's not really CRTP, is it? For it to be CRTP, CEdit would be class CEdit : public Base<CEdit> { ... };
  • @Prætorian: But that seems really weird for something like CEdit... also, I guess I was thinking of CWindowImpl when I wrote "CRTP". I'll remove that, thanks for pointing it out.
  • +1 for a practical example, thanks. But one question: Isn't that already solvable with a templated subclass, though? (e.g. FixedWindow<CEdit> rather than CEditT<FixedWindow>)
  • @Mehrdad: How would FixedWindow<CEdit> help if CEdit is the thing calling the offending function? Maybe I don't understand exactly what you mean.
  • Oooh yeah it wouldn't, my bad. I was thinking of someone else calling the function, not the class itself.
  • I guess my question is, why doesn't it inherit directly from CWindow in the first place?
  • Good question. That way it is not hard-coded to a particular window class implementation, just like ListNode isn't tied to a particular kind of ITEM. You could make your own window implementation, for instance, by customizing the standard one. Derive from it to make MyWindow and then you can instantiate CEditT<MyWindow>. The question could be reversed: why should we tie a utility class to a particular target class when we can template it and target it to a kind of target class that just has the right interface? It's a paradigm. ;)
  • In what scenario (practically speaking) would CEditT<T> ever be instantiated where T is not CWindow? (Is there any known use case for this?)
  • Hmm, good question. Even if there aren't, basically there is no good reaosn not to make CEditT be inconsistent with the framework. Someone somewhere is going to want CEditT<CWindowImpl<MyClass>> and be in for a rude surprise to find a monolithic CEdit.
  • Here is a Yahoo groups posting on exactly this subject: tech.groups.yahoo.com/group/wtl/message/5500
  • When is that actually useful (for CEditT and the like)?
  • @Mehrdad, a glance at the source for CEditT would probably answer that question. I don't have access to it right now or I'd do it myself. It's quite possible that it uses CRTP only to be consistent with all the other ATL classes.
  • This doesn't actually answer the question. It's not about CRTP. This question is about templatizing the base class, not the derived class to static_cast to.