
Hi Mark, You have introduced a third perspective - looks promising. Hope I can keep track of all the differences and still contribute in some useful manner.
[mailto:boost-bounces@lists.boost.org]On Behalf Of Mark Blewett
<snip>
class MyServant : public Servant { public: MyServant(Scheduler* scheduler) : Servant(scheduler) {} void do_fn(int x, int y) { std::cout << x << " " << y << std::endl; } };
class MyServant : public Servant { public: MyServant(Scheduler* scheduler) : Servant(scheduler), fn(this, &MyServant::do_fn) {} MethodProxy<MyServant, int, int> fn; private: void do_fn(int x, int y) { std::cout << x << " " << y << std::endl; } };
<snip> I understand the direction that both Matthew and yourself are heading. The resulting interface for clients of your class, is concise. Fully bound functions are a nice packaging and there are plenty of precendents. There is one design constraint that this direction would impose on clients, that rules it out as a solution for me. This doesnt necessarily interest you but just in case, I will try to paint the picture as briefly as I can. If active objects (i.e. classes deriving from Servant) communicate by calling methods defined in each other, then they have compile-time knowledge of each other. Reasonable assumption I suppose. However, it follows that every client of a particular object, i.e. an active object that calls a member of another active object, is itself required to provide a specific interface. That being the interface that the second object uses to respond. Returning to the db server example; every client must derive from a common class that defines all the members that the server might call. Perhaps like this; class DbServant : public Servant { public: DbServant(Scheduler* scheduler) : Servant(scheduler), fn(this, &DbServant::do_fn) {} MethodProxy<DbServant, int, int> fn; private: void do_fn(int x, int y) { std::cout << x << " " << y << std::endl; } }; class MyReadOnlyViewer : public DbServant { // Run a status display repeated around // the factory }; class MyViewerAndController : public DbServant { // Run a window with controls // for modifying the data model }; This (hopefully) seems like a reasonable circumstance. But as coded the db_server would be calling methods defined in DbServant when what you really want is different implementations for MyReadOnlyViewer and MyViewerAndController. I assume that with some twiddling your technique could accomodate these kind of requirements (given that you are still reading and still interested). Would the db_server also have a separate "db_interface" class? Also, if this kind of interface class technique has any legs is it also (potentially) dragging lots of implementation details along with it? Can that be avoided? Should it be? Cheers, Scott