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@eudoxos.de>
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@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users