|
Boost : |
Subject: Re: [boost] Formal Review Request: TypeErasure
From: Hite, Christopher (Christopher.Hite_at_[hidden])
Date: 2012-06-07 12:12:05
Chris:
>>> * people shouldn't use any to replace classic interfaces and virtual
>>> functions
Dave Abrahams:
>>Excuse me, but why not? Doing polymorphism this way eliminates all kinds of nastiness that we get with classic interfaces and virtual functions.
Luke:
> Perhaps we should make sure the documentation clearly states what kinds of nastiness the library allows us to avoid and how it is intended to be used. It solves a lot of problems ....
So the nice thing about the any vs. classic virtual functions is it is nonintrusive. Consider a library that defines this:
struct push_back_able{
virtual void push_back(int) =0;
};
void get_ints(push_back_able&);
vector<int>, list<int>, etc aren't derived from push_back_able and you can't/shouldn't go change stl containers to make it do it. So if you want to feed ints into a vector<int> you'll have to make a new class which isA push_back_able and references the vector.
At this point you've probably already thought of some kind of utility like:
template<typename T>
push_back_delegator<T> make_ push_back_delegator(T&);
So you can do this:
std::vector<int> v;
get_ints(make_ push_back_delegator(v));
any<> helps you do this, hopefully with less code.
=================================================================
Now I'm going to try to draw a counter example where I think virtual methods make more sense.
I've picked something with several functions with different signatures so nobody can argue it can be easily type-deleted as a functor concept.
struct session_handler{
virtual void handle_connect() =0;
virtual void handle_message(const message&) =0;
virtual void handle_disconnect() =0;
};
Now alternatively we could define an any<..., _self&> and hand that to session instead of session_handler&. I think that's a bad idea.
1) defining the any requires a bit more code: you' need to define boost:: type_erasure::concept_interface's to get the calls to look nice.
2) the language construct is already there and is cleaner to read. C++11 override also helps.
The main difference between these two examples is the dependency. STL should never depend on someone's ad-hoc push_back_able concept. By contrast someone writing my_session_handler knows his code is dependent on that interface. So he doesn't mind inheriting the base class, since it is just formalizing that relationship.
I support the boost style of code which has very few virtual methods exposed to the user (as opposed to something like ACE). However I still believe they make sense sometimes.
Chris
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk