Nope. Container-agnostic code is a red herring. Don't bother, you'll only be waisting your time. "Effective STL" covers this in detail in Chapter 1, item 2, far better than anything I could come up with. You might be able to come up with 'map' and 'everything else' versions of your code, but even that will have some unexpected side effects. Now, having said all that, here's an idea (I seem to be developing a habit of contradicting myself): Accept as part of the enumerator template an 'accessor', one that would default to returning the contents of the iterator, but could be replaced with something that extracted "->second". Your code would end up looking something like this: // WARNING: This code hasn't been anywhere near a compiler. template <typename T> struct accessor { typedef T::value_type accessee; accessee &operator()( T &t ) { return *T; } }; template <typename T> struct map_accessor { typedef T::value_type::second accessee; accessee &Map_Accessor( T &t ) { return t->second; } }; template <typename T, typename acc = Accessor<T>> EnumCols( T &begin, T &end, acc accessor ) { T cur; if(begin == end) return; // get matrix width size_t rows = acc( begin ).size(); for(int i = 0; i < rows; ++i) { cur = begin; while(cur != end) { // a useful EnumCols would have to take some // sort of function as a paramenter and use // it to replace DO_STUFF below DO_STUFF( acc(cur)[i] ); ++cur; } } } EnumCols( matrix.begin(), matrix.end(), Map_Accessor<matrix's type> ); // for maps or EnumCols( matrix.begin(), matrix.end()); // for everything else These function templates could either exist stand-alone, or as some sort of 'container-traits'. The traits tact would force you to wrap all the containers you actually wanted to use with templates that defined the appropriate traits, but would allow the actual enumeration code to be considerably cleaner (through default template params). But all this involves rolling your own code, which would place this conversation firmly in the "other" boost list. --Mark Storer Software Engineer Cardiff Software #include <disclaimer> typedef std::disclaimer<Cardiff> Discard; -----Original Message----- From: Antonio Piccolboni [mailto:antonio_piccolboni@affymetrix.com] Sent: Tuesday, September 24, 2002 12:01 PM To: Boost-Users@yahoogroups.com Subject: [Boost-Users] (unknown) Dear Boosters Suppose you have a matrix represented raw-wise with a vector< vector <float > > and you want to iterate over the coloumns. Easy with the projection adaptor. But life is never so easy. My matrix is represented raw wise by a map <vector <float> > and I need the same kind of iterator. There is no way I can get my code to compile. I think the problem is that vector iterators return values, map iterators retun pairs <key,value> (that is, references to the above). And this seems not only to doom my attempt at defining this n-th dim projection iterator, but even more so and fundamentally, it seem to preclude my ultimate goal of defining a projection for any container1 <containr2 < element_type > > where container2 two is random access. Any help would be appreciated and if I make it to the larger goal, I will return it to the community. Thanks Antonio Header #ifndef GRAPH_H #define GRAPH_H #include <boost/config.hpp> #include <vector> #include <iostream> #include <iterator> #include <algorithm> #include <boost/iterator_adaptors.hpp> //typedef pair<long, vector<float> > graph_element; typedef vector<float> graph_element; template <int index> struct select_component { typedef pair < long, graph_element > argument_type; typedef float result_type; const float & operator()(const graph_element & r) const { return r.second[index]; } float & operator()(graph_element & r) const { return r.second[index]; } }; #endif Would be test code #include "graph.h" #include <map> #include<vector> int main(int, char*[]) { typedef map < long, graph_element > graph; graph aGraph; aGraph[0].push_back(0.00); aGraph[0].push_back(0.01); aGraph[0].push_back(0.02); aGraph[1].push_back(0.10); aGraph[1].push_back(0.11); aGraph[1].push_back(0.12); aGraph[2].push_back(0.20); aGraph[2].push_back(0.21); aGraph[2].push_back(0.22); aGraph[3].push_back(0.30); aGraph[3].push_back(0.31); aGraph[3].push_back(0.32); boost::projection_iterator_generator < select_component < 0 >, graph::iterator >::type graph_first(aGraph.begin()), graph_last(aGraph.end()); copy(graph_first, graph_last, ostream_iterator<float>(cout, "\n")); cout << endl; } Post-modern error message cd /home/apicco/src/analysis/transcriptome/transmap/ g++ -g -I/home/apicco/install/boost_1_28_0 -o graph-test graph-test.C /home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp: In method `typename IteratorAdaptor::reference boost::projection_iterator_policies<AdaptableUnaryFunction>::dereferen ce (const IteratorAdaptor &) const [with IteratorAdaptor = boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int, graph_element>, pair<const long int, graph_element> &, pair<const long int, graph_element> *>, boost::projection_iterator_policies<select_component<0> >, float, float &, float *, boost::detail::default_argument, boost::detail::default_argument>, AdaptableUnaryFunction = select_component<0>]': /home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp:867: instantiated from `boost::iterator_adaptor<Base, Policies, Value, Reference, Pointer, Category, Distance>::operator* () const [with Base = _Rb_tree_iterator<pair<const long int, graph_element>, pair<const long int, graph_element> &, pair<const long int, graph_element> *>, Policies = boost::projection_iterator_policies<select_component<0> >, Value = float, Reference = float &, Pointer = float *, Category = boost::detail::default_argument, Distance = boost::detail::default_argument]' /usr/include/g++-3/stl_algobase.h:129: instantiated from `__copy (_InputIter, _InputIter, _OutputIter, input_iterator_tag, _Distance *) [with _InputIter = boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int, graph_element>, pair<const long int, graph_element> &, pair<const long int, graph_element> *>, boost::projection_iterator_policies<select_component<0> >, float, float &, float *, boost::detail::default_argument, boost::detail::default_argument>, _OutputIter = ostream_iterator<float>, _Distance = ptrdiff_t]' /usr/include/g++-3/stl_algobase.h:161: instantiated from `__copy_dispatch<_InputIter, _OutputIter, _BoolType>::copy (_InputIter, _InputIter, _OutputIter) [with _InputIter = boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int, graph_element>, pair<const long int, graph_element> &, pair<const long int, graph_element> *>, boost::projection_iterator_policies<select_component<0> >, float, float &, float *, boost::detail::default_argument, boost::detail::default_argument>, _OutputIter = ostream_iterator<float>, _BoolType = __true_type]' /usr/include/g++-3/stl_algobase.h:188: instantiated from `copy (_InputIter, _InputIter, _OutputIter) [with _InputIter = boost::iterator_adaptor<_Rb_tree_iterator<pair<const long int, graph_element>, pair<const long int, graph_element> &, pair<const long int, graph_element> *>, boost::projection_iterator_policies<select_component<0> >, float, float &, float *, boost::detail::default_argument, boost::detail::default_argument>, _OutputIter = ostream_iterator<float>]' graph-test.C:30: instantiated from here /home/apicco/install/boost_1_28_0/boost/iterator_adaptors.hpp:1247: no match for call to `(const select_component<0>) (pair<const long int, graph_element> &)' graph.h:19: candidates are: const float &select_component<index>::operator() (const graph_element &) const [with int index = 0] graph.h:22: float &select_component<index>::operator () (graph_element &) const [with int index = 0] Compilation exited abnormally with code 1 at Tue Sep 24 11:14:11 Info: <http://www.boost.org> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl> Unsubscribe: <mailto:boost-users-unsubscribe@yahoogroups.com> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
participants (1)
-
Mark Storer