Boost logo

Boost :

From: Sam Partington (Sam.Partington_at_[hidden])
Date: 2003-02-19 04:17:13


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


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