[Cross-posted comp.lang.c++ and comp.lang.python]
Consider the following code, from an example usage of some C++ support for
Python I'm working on, "cppy":
<code>
struct Noddy
{
PyPtr first;
PyPtr last;
int number;
Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
: number( 0 )
{
// ... some initialization here
}
PyPtr name()
{
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,
Exposition()
.method(
L"name", CPPY_METHOD_FORWARDER( name ),
L"Return the name, combining the first and last name"
)
.attribute(
L"first", CPPY_GETSET_FORWARDERS( first ),
L"first name"
)
.attribute(
L"last", CPPY_GETSET_FORWARDERS( last ),
L"last name"
)
.attribute(
L"number", CPPY_GETSET_FORWARDERS( number ),
L"noddy number"
)
)
{}
};
</code>
Originally e.g.
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 >
struct ForwardersForGetAndSet
{
// 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 ) \
::progrock::cppy::forwardersGetSet( \
&CppClass::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.
He he.
Perhaps this trick is well-known already, but it was new to me, so! :-)
Cheers,
- Alf
--
blog at <url: http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list