[C++-sig] Re: self_ns:: necessary when exposing stringification?

David Abrahams dave at boost-consulting.com
Sat Feb 14 18:06:36 CET 2004


Andreas Kloeckner <ak at ixion.net> writes:

> Hey everybody,
>
> when writing a wrapper recently, I wanted to expose stringification by
> writing
>
> 8<-----------------------------------------------------------------------------
> using namespace boost::pyton;
>
> BOOST_PYTHON_MODULE(...)
> {
>   class_<...>(...)
>     .def(str(self));
> }
> 8<-----------------------------------------------------------------------------
>
> which resulted in the following error message:
>
> 8<-----------------------------------------------------------------------------
> ... instantiated from various points... (see below for complete error
> message)
> /home/ak/work/boost/boost/python/def_visitor.hpp:32: error: no matching
>    function for call to `boost::python::api::object::visit(
>    boost::python::class_<LLMatWrapper<double>,
>    boost::python::bases<spmatrix::MatrixOperator<double>, boost::mpl::void_,
>    boost::mpl::void_, boost::mpl::void_, boost::mpl::void_, boost::mpl::void_,
>    boost::mpl::void_, boost::mpl::void_, boost::mpl::void_, boost::mpl::void_>,
>    boost::python::detail::not_specified, boost::python::detail::not_specified>&
>    ) const'
> 8<-----------------------------------------------------------------------------
>
> So, the compiler must have picked up the "str" function from the object
> API

It's a class.

> , and then class_ tries to apply its visitor magic and fails
> miserably.
>
> This theory is confirmed by the fact that 
>
> 8<-----------------------------------------------------------------------------
>   class_<...>(...)
>     .def(self_ns::str(self));
> 8<-----------------------------------------------------------------------------
>
> actually works. Same thing happens with the BPL test case
> "operators".

Not AFAICT, unless you explicitly add #include <boost/python/str.hpp>.

> This strikes me as odd since the unit test sheet published on boost.org
> says that this should work with 3.2.3. (which it doesn't, at least not
> with Debian's)

I don't believe you have an unmodified installation of Boost 1.31.0

> Do you want me to try any other solutions besides adding self_ns? 
> Is there a good reason for this behavior besides 
> "gcc's function lookup is broken"?  

Nothing broken about it, AFAICT.

> What can I do to help you provide a general solution?

The general solution is "don't use using-directives"

That, however, is draconian in this case.  We could make
boost::python::str visitable, just for the sake of this ambiguity,
but that also feels very wrong.

I'm afraid none of my ideas at this point are very good.  The one
that I definitely like so far is changing str's templated constructor
to:

    template <class T>
    explicit str(
        T const& other
      , typename disable_if<is_same<T,self_t> >::type* = 0
    )
     : base(object(other))
    {
    }

That stops the erroneous construct in the right place, but I don't
know how to get the compiler to stop preferring boost::python::str
over boost::python::self_ns::str.  Even nesting the class into an
enclosing namespace doesn't seem to do much good.

I suggest taking a good look at the C++ standard (with the technical
corrigendum) and considering the rules that govern the choice of
classes vs. functions in unqualified calls like this one.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list