Figure 1    ATL's IdispatchImpl

 template <
     class T, 
     const IID* piid, 
     const GUID* plibid, 
     WORD wMajor = 1,
     WORD wMinor = 0, 
     class tihclass = CComTypeInfoHolder
 >
 class IDispatchImpl : public T
 {
 public:
     typedef tihclass _tihclass;
     IDispatchImpl() {_tih.AddRef();}
     ~IDispatchImpl() {_tih.Release();}
 
     STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
       {*pctinfo = 1; return S_OK;}
 
     STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
       {return _tih.GetTypeInfo(itinfo, lcid, pptinfo);}
 
     STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
                              LCID lcid, DISPID* rgdispid)
       {return _tih.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);}
 
     STDMETHOD(Invoke)(DISPID dispidMember, REFIID, LCID, WORD wFlags, 
                       DISPPARAMS* pdispparams, VARIANT* pvarResult,
                       EXCEPINFO* pexcepinfo, UINT* puArgErr)
       {return _tih.Invoke((IDispatch*)this, dispidMember, riid, lcid, wFlags, 
                           pdispparams, pvarResult, pexcepinfo, puArgErr);}
 protected:
       static _tihclass _tih;
       static HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo)
       {return _tih.GetTI(lcid, ppInfo);}
 };