Consider the following code, from an example usage of some C++ support for
Python I'm working on, "cppy":
Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
: number( 0 )
// ... some initialization here
return (PyString( first ) + L" " + PyString( last )).pyPtr();
struct NoddyPyClass: PyClass< Noddy >
typedef PyClass< Noddy > Base;
NoddyPyClass( PyModule& m, PyString const& name, PyString const& doc )
: Base( m, name, doc,
L"name", CPPY_METHOD_FORWARDER( name ),
L"Return the name, combining the first and last name"
L"first", CPPY_GETSET_FORWARDERS( first ),
L"last", CPPY_GETSET_FORWARDERS( last ),
L"number", CPPY_GETSET_FORWARDERS( number ),
CPPY_GETSET_FORWARDERS( number ),
had to be written as
CPPY_GETSET_FORWARDERS( int, number ),
because in order to use a compile time member pointer as template actual
argument, one needs to supply the member type as a separate template argument.
E.g. the template might look like
template< class Class, class MemberType, MemberType Class::*pMember >
// Some definitions here, hardwiring that compile time member pointer!
Apparently there was no way around the user repeating explicitly the member type
that the compiler already knew about... It seemed akin to deducing the return
type of a function. Difficult in C++98 (although Boost does a fair job).
But then it seemed that I'm not totally senile yet, for this occurred to me:
#define CPPY_GETSET_FORWARDERS( name ) \
).themForwarders< &CppClass::name >()
Here forwardersGetSet is a templated function that via argument type deduction
produces an instance of a templated struct, thereby "knowing" the member type,
which struct in turn has a member function templated on the member pointer,
which the macro supplies *twice*, once as run-time arg and once as compile-time.
Perhaps this trick is well-known already, but it was new to me, so! :-)
blog at <url: http://alfps.wordpress.com>