[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;
> {
>   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

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

    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

More information about the Cplusplus-sig mailing list