[C++-sig] Re: How to expose virtual function with defaultarguments in boost.python ?

David Abrahams dave at boost-consulting.com
Tue Dec 7 00:11:39 CET 2004


Baptiste Lepilleur wrote:
> ----- Original Message ----- 
> From: "David Abrahams" <dave at boost-consulting.com>
> To: <c++-sig at python.org>
> Sent: Monday, December 06, 2004 3:11 PM
> Subject: [C++-sig] Re: How to expose virtual function with defaultarguments
> in boost.python ?
> 
> 
> 
>>Baptiste Lepilleur wrote:
>>
>>>----- Original Message ----- 
>>>From: "David Abrahams" <dave at boost-consulting.com>
>>
>>
>>>>1. Use new-style polymorphism.
>>
>>[...]
>>
>>>Is there a performance hit if I always use the VC6/7 work-around in the
>>>overridden virtual method ? (=> should I used the #if BOOST_WORKAROUND
> 
> all
> 
>>>over the place ?)
>>
>>No performance hit; it's just uglier.  But if you need portable code,
>>just use the vc6/7 method.
> 
> 
> This solution passes all my simple test cases. I'm now tackling a full
> generation of the pyogre binding to "polish" the generator. When compiling
> the full binding, I stumbled on the following warning (I'm compiling with
> VC++ 7.1):
> 
> build\pyogre_\BillboardSet.cpp(303) : warning C4172: returning address of
> local variable or temporary
> 
> Ogre::String is just a typedef on std::string. This code is the
> implementation of the overriden virtual method in the wrapper class. The
> code generation the warning follow:
> 
> ---
>     const Ogre::String& getMaterialName() const {
>         if (override f = this->get_override("getMaterialName"))
> #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // Workaround for vc6/vc7
>             return call< const Ogre::String& >( f.ptr());
> #else
>             return f(  );   /// <<< *** warning on this line ***
> #endif

Why not just

               return call< const Ogre::String& >( f.ptr());

??

>         return Ogre::BillboardSet::getMaterialName();
>     }
> ---
> 
> Do you have any idea on how to "remove" this warning? 

The warning is a compiler bug; I reported it late in the vc7.1 release 
cycle and they were not inclined to fix it.

> The old-style way:
> return call_method< const Ogre::String& >(py_self, "getMaterialName");
> does not generate that warning.

  Just write what I suggested above.

> By the way, what is the "right" way to retrieve the PyObject* associated to
> the wrapper ? The only thing I found is:
> boost::python::detail::wrapper_base_::get_owner(). Seems to be hidden too
> deeply to be of legal use. 

I didn't want to publish it until I was sure someone needed it.  Why do 
you want it?

> Anyway, would replacing the line causing the
> warning by:
> 
> PyObject *py_self = boost::python::detail::wrapper_base_::get_owner(
> *this );
> return call_method< const Ogre::String& >(py_self, "getMaterialName");
> 
> works correctly ?

Blick!  What's wrong with just using the vc6/7 workaround code?

> 
> [...]
> 
>>>>2. qualify your calls to  set:
>>>>
>>>>return self.VirtualReturnValuePolicy::set(p0);
>>>
>>>
>>>I don't see how this would change anything. self is already of type
>>>'VirtualReturnValuePolicy &'.
>>
>>It prevents VirtualReturnValuePolicy_Wrapper::set from being called
> 
> instead.
> 
> Somehow, I managed to forget that 'set' is a virtual function (nothing short
> of amazing!). Will try this later.

You don't need to do both things, I don't think.  One or the other will do.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com




More information about the Cplusplus-sig mailing list