c++ - Funky template bug - a trimmed down example
- "Matthew Wilson" <matthew stlsoft.org> May 20 2003
- Richard Grant <fractal clark.net> May 20 2003
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








Richard Grant <fractal clark.net>