www.digitalmars.com         C & C++   DMDScript  

c++ - Another template bug - confusion between pointer-to-member and plain pointer

COMSTL has some overloads of a template function that handle boilerplate
member accessor functionality. Alas, DMC++ doesn't work with them.

template <as_typename_param_k C, as_typename_param_k T>
inline HRESULT get_MemberValue(C *cls, T *ret, T C::*mem)
{
    return (ret == 0) ? E_POINTER : (*ret = cls->*mem, S_OK);
}

template <as_typename_param_k C>
inline HRESULT get_MemberValue(C *cls, BSTR *ret, CComBSTR C::*mem)
{
    return (ret == 0) ? E_POINTER : (*ret = (cls->*mem).Copy(), (*ret != 0 ?
S_OK :  E_OUTOFMEMORY));
}


In the following class

class SimpleServer
{
public:
 SimpleServer()
  : m_bstrUserName("[No username]")
  , m_logonKey(-1)
 {}

// Property accessors
public:
 STDMETHODIMP SimpleServer::get_UserName(/* [retval][out] */ BSTR *pVal)
 {
  return get_MemberValue(this, pVal, &SimpleServer::m_bstrUserName);
 }

 STDMETHODIMP SimpleServer::put_UserName(/* [in] */ BSTR newVal)
 {
  return put_MemberValue(this, newVal, &SimpleServer::m_bstrUserName);
 }

 STDMETHODIMP SimpleServer::get_LogonKey(/* [retval][out] */ short *pVal)
 {
  return get_MemberValue(this, pVal, &SimpleServer::m_logonKey);
 }

 STDMETHODIMP SimpleServer::put_LogonKey(/* [in] */ short newVal)
 {
  return put_MemberValue(this, newVal, &SimpleServer::m_logonKey);
 }

// Members
protected:
 CComBSTR m_bstrUserName;
 short  m_logonKey;
};

It gives the following error

atlstl\property_accessors_test\property_accessors_test.cpp(46) : Error: no
match for function 'get_MemberValue(SimpleServer*,wchar_t **,wchar_t **)'
atlstl\property_accessors_test\property_accessors_test.cpp(51) : Error: no
match for function 'put_MemberValue(SimpleServer*,wchar_t *,wchar_t **)'
--- errorlevel 1

It seems that it cannot work out that the third parameter is a pointer to
member, rather than a simple pointer.
Apr 07 2003