Boost logo

Boost :

From: Matthias Hoffrichter (TrollCoder_at_[hidden])
Date: 2003-02-23 11:12:03


Hi!

Thank you Sam. That solved my problem. For now it works fine with
static_cast. :-)
The method now looks like this:

 template<typename WindowType> void SetEventHandler(UINT uMessage, LRESULT
(WindowType::*Function)(MSG&), CWindow* pWindow = NULL) {
  if(pWindow == NULL) {
   pWindow = this;
  }
  MessageMap[uMessage] = boost::bind(Function,
static_cast<WindowType*>(pWindow), _1);
 }

cu,
Matthias

----- Original Message -----
From: "Sam Partington" <Sam.Partington_at_[hidden]>
To: "Boost mailing list" <boost_at_[hidden]>
Sent: Wednesday, February 19, 2003 10:17 AM
Subject: Re: [boost] Encapsulate boost::bind in a template method

> Hi
>
> It won't compile because you're trying to bind a (CButton::*)() function
to
> CWindow*. See bjarne 15.5.1
>
> Change the line marked to
>
> boost::function<long> EventFunction = boost::bind(Function,
> static_cast<T*>(this));
>
> Or you could use dynamic_cast to check that the cast is valid:
>
> if (T* that = dynamic_cast<T*>(this))
> {
> boost::function<long> EventFunction = boost::bind(Function, that);
> }
>
> Though you can make this less of a problem if you declare your handler
> functions private, so that you are less likely to be able to pass duff
> member function pointers. e.g.
>
> class CWindow
> {
> // as before
> };
>
> class CWindowA : public CWindow
> {
> private:
> long OnPaint();
> };
>
>
> class CWindowB : public CWindow
> {
> public:
> CWindowB()
> {
> SetEventHandler(&CWindowA::OnPaint); // won't compile now, as
> CWindowA::OnPaint is inaccessible
> }
> private:
> long OnPaint();
> };
>
> I think I would then be happy to use boost::polymorphic_downcast
> (http://www.boost.org/libs/conversion/cast.htm)
>
> HTH
>
> Sam
>
> PS I havn't checked the code, so apologies for any typos
>
> ----- Original Message -----
> From: Matthias Hoffrichter
> To: boost_at_[hidden]
> Sent: Wednesday, February 19, 2003 3:56 AM
> Subject: [boost] Encapsulate boost::bind in a template method
>
>
> Hi,
>
> I want to encapsulate boost::find in a template method in a base class for
> easier use.
> Here is some code:
>
> #include <boost/function.hpp>
> #include <boost/bind.hpp>
>
> class CWindow {
> public:
> CWindow() {
> SetEventHandler(&CWindow::OnCreate); // this call works
> }
> long OnCreate() {
> return 0;
> }
> template<typename T> void SetEventHandler(long (T::*Function)()) {
> **************
> boost::function<long> EventFunction = boost::bind(Function, this);
> // ...
> // Add EventFunction into a std::map
> }
> };
>
> class CButton : public CWindow {
> public:
> CButton() {
> SetEventHandler(&CButton::OnPaint); // this call doesn't compile
> }
> long OnPaint() {
> return 0;
> }
> };
>
> int main() {
> return 0;
> }
>
> The SetEventHandler call in the CButton's constructor generates 2 errors
on
> VC++ 7.0:
>
> mem_fn_template.hpp(37): error C2440: 'newline' : 'CWindow *' can't be
> converted in 'CButton *'
> mem_fn_template.hpp(37): error C2647: '->*' : 'const
> boost::_mfi::mf0<R,T>::F' can't be dereferenced in '$T'
>
> It also doesn't compile on g++ 3.2.
>
> If I copy & paste the template method in every derived class the code
> compiles well, but this can't be a good soluation. :(
> And if i outcomment "boost::function<long> EventFunction" it also works,
but
> of course I need to work with boost::bind's return value. ;-)
>
> Is there a way to solve this problem?
>
> cu,
> Matthias
>
> _______________________________________________
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk