The fun of templates does not stop at global functions. Oh, no. You can create member function templates as well. As of Visual C++ 6.0, the definition of IUnknown has been augmented with a member function template for QueryInterface: struct IUnknown { ... template <class Q> HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) { return QueryInterface(__uuidof(Q), (void**)pp); } } Before the member function template, all calls to QueryInterface had to be sure to match up the interface type and the interface identifier: void Fly(IUnknown* punk) { IBird* pbird = 0; punk->QueryInterface(IID_ICat, (void**)&pbird); // Oops! punk->QueryInterface(IID_IBird, (void**)pbird); // Double oops! punk->QueryInterface(IID_IBird, (void**)&pbird); // OK pbird->Fly(); } On the other hand, with the QueryInterface member function template, the type of the interface suffices: void Fly(IUnknown* punk) { IBird* pbird = 0; punk->QueryInterface(&pbird); // __uuidof uses to determine IID pbird->Fly(); } In effect, member function templates add new member functions of a class, just as function templates add new global functions based on use. |