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
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 ); //
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 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 (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
> 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
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include
//typedef pair 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 &, pair *>,
boost::projection_iterator_policies >, 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::operator* () const [with
Base = _Rb_tree_iterator,
pair &, pair *>, Policies =
boost::projection_iterator_policies >, 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 &, pair *>,
boost::projection_iterator_policies >, 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 &, pair *>,
boost::projection_iterator_policies >, 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 &, pair *>,
boost::projection_iterator_policies >, 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 &)'
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/