Boost logo

Boost Users :

Subject: Re: [Boost-users] [Bind] Representing a member function as C function pointer?
From: Alex MDC (alex.mdc_at_[hidden])
Date: 2009-02-02 03:51:09


In a word, no. boost::bind returns a function object (i.e. callable with the
() operator), not a C-style function pointer.

If your XmlParser class is just using the callbacks internally then there's
not much you can do, other than delegating to member functions. However if
you want to expose these callbacks to your class users then you can probvide
nicer boost::function style handlers and delegate to them, something like:

class XmlParser
{
public:
    typedef boost::function<void, const char*, const char**>
StartElementHandler;
    typedef boost::function<void, const char*> EndElementHandler;

    void SetElementHandler(StartElementHandler startHandler,
EndElementHandler endHandler)
    {
        _startHandler = startHandler;
        _endHandler = endHandler;
    }

    static void expatStartElementHandler (void* userData, const char*
element, const char** attr)
    {
        XmlParser* xmlParser = reinterpret_cast<XmlParser*>(pUserData);
        xmlParser->_startElement (element, attr);
    }

    static void expatEndElementHandler (void* pUserData, const char*
element)
    {
        XmlParser* xmlParser = reinterpret_cast<XmlParser*>(pUserData);
        xmlParser->_endElement (element);
    }

    // rest of class

private:
    StartElementHandler _startHandler;
    EndElementHandler _endHandler;
};

Hope this helps,

Alex

2009/2/2 Roland Bock <rbock_at_[hidden]>

> Hi,
>
> maybe this is stupid, but I wonder if my code could become more elegant. I
> am using expat for XML parsing, which is working fine, but could be nicer:
>
> I have a class (XmlParser) which provides all the handlers for SAX parsing
> required by expat, but I can't figure out how to use them directly?
>
> When initializing expat, I give it a pointer to an XmlParser object and
> then register handlers:
>
> --------------------------
> static void expatStartElementHandler (void* pUserData,
> const char* element,
> const char** attr)
> {
> XmlParser* xmlParser = reinterpret_cast<XmlParser*>(pUserData);
> xmlParser->startElement (element, attr);
> }
>
> static void expatEndElementHandler (void* pUserData,
> const char* element)
> {
> XmlParser* xmlParser = reinterpret_cast<XmlParser*>(pUserData);
> xmlParser->endElement (element);
> }
>
> void XmlParser::init()
> {
> parser_ = XML_ParserCreate ("UTF-8");
> XML_SetUserData (parser_, this);
> XML_SetElementHandler (parser_,
> expatStartElementHandler,
> expatEndElementHandler);
> //...
> }
> -------------------------
>
> I would prefer to get rid of those static non-member functions and their
> reinterpret_cast and do something like
>
> // does not work
> XML_SetElementHandler (parser_,
> boost::bind(&XmlParser::startElement, this, _2, _3),
> boost::bind(&XmlParser::endElement, this, _2));
>
>
>
> Is there a nice way to do this with bind?
>
>
> Regards,
>
> Roland
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net