callback revisited

M

ma740988

I was perusing modern C++ designs and the loki library and I might add
I hit overload when I hit select part of that book and the library.
The template _stuff_ is very intense ...... whew!!

Oso long ago I found - for the most part a nice callback class.
Current approach works well for functions that accept no argments.
Trouble is I now need to tweak the code to accomodate the case for an
integer argument. How could I achieve this?

// file sltest.h
#ifndef SLTEST_H
#define SLTEST_H

class CallbackBase
{
public:
virtual void operator()() const { };
virtual ~CallbackBase() = 0;
};

CallbackBase::~CallbackBase() { }
template<typename T>
class Callback : public CallbackBase
{
public:
typedef void (T::*F)();
Callback( T& t, F f ) : t_(&t), f_(f) { }
void operator()() const { (t_->*f_)(); }
private:
T* t_;
F f_;
};

template<typename T>
Callback<T> make_callback( T& t, void (T::*f) () )
{
return Callback<T>( t, f );
}
// std::auto_ptr version ... akin to the above

If it's in the two hard pile then I'll end up having to go study the
loki library and re-read those chapters of Modern C++ design

Thanks
 
V

Victor Bazarov

I was perusing modern C++ designs and the loki library and I might add
I hit overload when I hit select part of that book and the library.
The template _stuff_ is very intense ...... whew!!

Oso long ago I found - for the most part a nice callback class.
Current approach works well for functions that accept no argments.
Trouble is I now need to tweak the code to accomodate the case for an
integer argument. How could I achieve this?

// file sltest.h
#ifndef SLTEST_H
#define SLTEST_H

class CallbackBase
{
public:
virtual void operator()() const { };

You should probably add an 'int' argument to the operator function call
above. BTW, did you mean to make it pure as well?
virtual ~CallbackBase() = 0;
};

CallbackBase::~CallbackBase() { }
template<typename T>
class Callback : public CallbackBase
{
public:
typedef void (T::*F)();
^^^^^^^^^^^^^^
Add an 'int' argument to this declaration.
Callback( T& t, F f ) : t_(&t), f_(f) { }
void operator()() const { (t_->*f_)(); }

Add an 'int' argument to this function too and pass it along to
the member.
private:
T* t_;
F f_;
};

template<typename T>
Callback<T> make_callback( T& t, void (T::*f) () )
.. ^^^^^^^^^^^^^^^
The 'f' argument declaration has to change here too.
{
return Callback<T>( t, f );
}
// std::auto_ptr version ... akin to the above

V
 
M

ma740988

Vic, I envisioned what you alluded to. Those changes require a
'separate' class. I was hoping to maintain one class. So now:

class CallbackBase
{
public:
virtual void operator()() const { }; // no argument
virtual void operator()(int) const { }; // int argument
virtual ~CallbackBase() = 0;
};

CallbackBase::~CallbackBase() { }
template<typename T>
class Callback : public CallbackBase
{
public:
typedef void (T::*F)(); <--------- This
presents a problem
// typedef void (T::*F)(int); <--------- This
presents a problem
Callback( T& t, F f ) : t_(&t), f_(f) { }

void operator()() const { (t_->*f_)(); }
void operator()(int) const { (t_->*f_)(int); }

private:
T* t_;
F f_;
};

template<typename T>
Callback<T> make_callback( T& t, void (T::*f) () )
{
// stuff
}

template<typename T>
Callback<T> make_callback( T& t, void (T::*f) (int idx) )
{
// stuff
}
 
D

Dan Cernat

Vic, I envisioned what you alluded to. Those changes require a
'separate' class. I was hoping to maintain one class. So now:

class CallbackBase
{
public:
virtual void operator()() const { }; // no argument
virtual void operator()(int) const { }; // int argument
virtual ~CallbackBase() = 0;
};

CallbackBase::~CallbackBase() { }
template<typename T>
class Callback : public CallbackBase
{
public:
typedef void (T::*F)(); <--------- This
presents a problem
// typedef void (T::*F)(int); <--------- This
presents a problem
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
you are trying to declare the type F twice here
once as a pointer to a function with no arguments and the secon time as
a pointer to a function with an angument of type int. can't do that.
make up your mind. or don't use typedefs at all.

Callback( T& t, F f ) : t_(&t), f_(f) { }

void operator()() const { (t_->*f_)(); }
void operator()(int) const { (t_->*f_)(int); }

private:
T* t_;
F f_;
^^^^^^^^^^^^ what F are you reffering here the firs one or the second
one?
<snip>

/dan
 
M

ma740988

|| you are trying to declare the type F twice here
I knew that I was just trying to illustrate the point.

| or don't use typedefs at all
Good point, one solution lies here...

One other question with respect to the following. All indications seem
to suggest that the following is NOT a wise move.

class Base {
static std::vector < std::auto_ptr< CallbackBase > > my_callback;
/// vector of auto_ptrs..
public:
// stuff
};
 
M

ma740988

|| you are trying to declare the type F twice here
I knew that I was just trying to illustrate the point.

| or don't use typedefs at all
Good point, one solution lies here...

One other question with respect to the following. All indications seem
to suggest that the following is NOT a wise move.

class Base {
static std::vector < std::auto_ptr< CallbackBase > > my_callback;
/// vector of auto_ptrs..
public:
// stuff
};

Potential pitfalls?
 
V

Victor Bazarov

I knew that I was just trying to illustrate the point.

Good point, one solution lies here...

One other question with respect to the following. All indications
seem to suggest that the following is NOT a wise move.

class Base {
static std::vector < std::auto_ptr< CallbackBase > > my_callback;
/// vector of auto_ptrs..
public:
// stuff
};

Potential pitfalls?

std::auto_ptr cannot be stored in a container, it doesn't meet the
requirements. You need to roll your own or use some other solution.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top