c++ - Funky template bug - a trimmed down example
- Matthew Wilson (68/68) May 20 2003 Walter, as promised, here's a trimmed down example (an extract from COMS...
- Richard Grant (11/15) May 20 2003 explicit std_mem_fun_t(R (STDAPICALLTYPE T::*pmfn)()) : m_f(pmfn)
Walter, as promised, here's a trimmed down example (an extract from COMSTL). It's still not tiny, but is self-contained and as small as can be. This code works with Borland (5.5, 5.6), Intel (6 & 7), VC++ (5, 6, 7), G++ (2.95 & 3.2), Metrowerks CodeWarrior (7 & 8). #include <windows.h> #include <algorithm> #include <functional> #ifndef __DMC__ using std::unary_function; using std::for_each; #endif /* __DMC__ */ template<typename R, typename T> class std_mem_fun_t : public unary_function<T*, R> { public: typedef R (STDAPICALLTYPE T::*method_type)(); public: explicit std_mem_fun_t(method_type pmfn) : m_f(pmfn) {} R operator ()(T *pt) const { return (pt->*m_f)(); } private: method_type m_f; }; template <class R, class T> inline std_mem_fun_t<R, T> std_mem_fun(R (STDAPICALLTYPE T::*f)()) { return std_mem_fun_t<R, T>(f); } int main() { // Dimension of the array const int C_UNKNOWNS = 10; // This is the CLSID for the GIT, though it could be anything really static const CLSID _CLSID_WidelyAvailableStdObject = { 0x00000323 , 0x0000 , 0x0000 , { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; ::CoInitialize(NULL); LPUNKNOWN unknowns[C_UNKNOWNS]; // Create them for(int i = 0; i < C_UNKNOWNS; ++i) { if(FAILED(::CoCreateInstance( _CLSID_WidelyAvailableStdObject, NULL, CLSCTX_ALL, IID_IUnknown, reinterpret_cast<void**>(&unknowns[i])))) { unknowns[i] = NULL; } } LPUNKNOWN *begin = unknowns; LPUNKNOWN *end = begin + C_UNKNOWNS; // Doesn't work for temporaries here ... for_each(begin, end, std_mem_fun(&IUnknown::Release)); // ... or in explicit form either std_mem_fun_t<ULONG, IUnknown> fn(&IUnknown::Release); ::CoUninitialize(); return 0; }
May 20 2003
typedef R (STDAPICALLTYPE T::*method_type)();useful for external chatter since no "typdef template <class.." :-(.explicit std_mem_fun_t(method_type pmfn) : m_f(pmfn)explicit std_mem_fun_t(R (STDAPICALLTYPE T::*pmfn)()) : m_f(pmfn) Something amiss with typdef inside the class here.. since specific reference to the member function pointer works.method_type m_f;R ( STDAPICALLTYPE T::*m_f)(); Still something wrong with typedef on template member pointers here, but this works. So someone needs to give Walter a targeted test case with member function pointer typedefs in template classes, since they are probably getting the wrong sig. I don't have all the cocreate stuff, but this compiled for me. Richard
May 20 2003