Is this template <class T> operator->*( ... ) for pointer to data members and pointer to member function with void argument potentially ambigous?
Hi,
the following code defines the operator->* on a templated class R<T>,
such that having an object R<T> a, which
includes a pointer p to an object of class T, and a pointer f to a
member function of T: double (T::*f)(), the following
construct can be used:
a->*f()
which is supposed to actually call p->*f(). The same should be
possible for a data member.
Unfortunately, the code does not compile in 64bit. The compiler (MS
VS2008) complains that the template parameter for the operator->*
could be equally well interpreted as a pointer to a member function
returning double, or as a pointer to a double data member. On 32bit
the same code compiles fine.
Is this a general ambiguity in my code, or is this rather a compiler
specific issue? Any hint on this topic is
appreciated. It would be helpful to be able to use this redefined
operator, instead of having to write the low
level version.
A complete code example is attached.
Please respond to the news group, or write to <martin dot frerichs at
googlemail dot com>.
Thanks and regards, Martin
----------------------- begin of code
----------------------------------------------------------------------------------------
// Breaks also with int, probably others types as well
#define DATATYPE double
template <class T> class R;
class A;
template <class D> struct F {
R<A> &m_r;
D(A::*m_t)();
F( R<A> r, D(A::*t)() ) : m_t(t), m_r(r) {}
D operator()() { return ((*m_r).*m_t)(); }
};
template <class D> F<D> make_F( R<A> r, D(A::*f)() ) {
return F<D>( r, f );
}
template <class T> class R {
T* m_pt;
public:
R<T>( T* pt ) : m_pt(pt) {}
T& operator*() const { return *m_pt; }
T* operator->() const { return m_pt; }
///////////////////////////////////////
// operator->* for R<T>, so that (r->*f)() for void arg member
functions and r->*d for
// public data members works, instead of having to use
((*r).*f)() or (*r).*d
// Data member
template <typename D>
friend D const& operator->*( R<T> const& r, D const T::* m_pd ) {
return (*r).*m_pd;
}
template <typename D>
friend D& operator->*( R<T> const& r, D T::* m_pd ) {
return (*r).*m_pd;
}
template <typename D>
friend typename F<D> operator->*( R<A> const& r, D(A::*f)() ) {
return make_F( r, f );
}
};
class A {
DATATYPE m_nData;
public:
A( DATATYPE const& nData, DATATYPE const& nPublicData ) : m_nData
( nData ), m_nPublicData(nPublicData) {}
DATATYPE member() { return m_nData; }
DATATYPE m_nPublicData;
};
DATATYPE demonstrateProblem() {
DATATYPE (A::*pMember)() = &A::member;
DATATYPE A::*pPublicData = &A::m_nPublicData;
A aObject(333,333);
R<A> aR(&aObject);
return aR->*pPublicData + (aR->*pMember)();
}
#undef DATATYPE
--------------------------------- end of code
-------------------------------------------------------------------------------------------
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]