On Thu, 23 Jan 2003, David Abrahams wrote:
> Douglas Paul Gregor <[EMAIL PROTECTED]> writes: > > > Why don't we have > > > > mpl::list<int, float, double, std::string> list_of_types; > > for_each(list_of_types.begin(), list_of_types.end(), f); > > > > ? > > > > Then an unqualified for_each call can handle type sequences, heterogeneous > > containers (e.g., tuple), and run-time sequences (e.g., vector). It's been > > done before, elsewhere, so why don't we do it in MPL? > > It's clever, but I'm not sure what problem it's solving. I mentioned this before and cited the paper "Static Data Structures: Reconciling Template Metaprogramming and Generic Programming": http://aspn.activestate.com/ASPN/Mail/Message/1304415 The title says it all: we have generic programming and template metaprogramming, and they complement each other nicely, but at the barrier between them I feel that we have a kludge. MPL and STL are built on the same abstractions, with similar naming schemes and similar style, so why is it that at the bridge between the two we have something that looks like neither? I think the for_each syntax I'm referring to is a clean bridge between the two, because it (logically, if not in code) maps the syntax of STL iterators to the syntax of MPL iterators in standard algorithm calls. The paper I referred to gave the most compelling argument for having precisely the same syntax at the bridge: you can test with the run-time version (short compile times) and release with the compile-time version (short execution times): they needed only to switch the object from std::vector to a compile-time vector, wait for KAI C++ to grind away for 24 hours, and they got 171 times the performance. > AFAICT it > doesn't solve the problem that Andrei was pointing at. You mean the front/pop_front issue? > It also has at > least one problem: it is intrusive on sequence types, requiring them > to have begin()/end() member functions. If this was the only way to > do it, it would break interoperability with 3rd-party type sequences. > > -Dave That's easy to fix---I was just trying to keep the example small. A few extra abstractions would be needed: namespace mpl { // Special type that for_each can pick up on template<typename Iterator> struct iterator { typedef Iterator type; }; // Stores an MPL sequence defined by an iterator range template<typename Begin, typename End> struct sequence { iterator<Begin> begin() const { return iterator<Begin>(); } iterator<End> end() const { return iterator<End>(); } }; template<typename Begin, typename End, typename F> F for_each(iterator<Begin> first, iterator<End> last, F f) { // ... } } Just stick your third-party iterators into sequence<> and you're all set; I'd expect that mpl::list, mpl::vector, etc. would just derive from mpl::sequence to reduce the amount of typing in the common case. Doug _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost