Topic: Why no implicit conversion from Container to Iterator?
Author: Dean Brettle <brettle@picard.jmb.bah.com>
Date: 1995/06/12 Raw View
Forgive me if this is a FAQ. Why is there no implicit conversion from a
container to an iterator "pointing to" the first object in the container? This
seems important for writing generic algorithms which work on multi-level data
structures (i.e. containers of containers). Consider the following short
program:
#include <vector.h>
// Define a generic function which we want to work on a container of
// containers.
template<class MajorIterator, class MinorIterator,
class MajorDistance, class MinorDistance, class T>
void fill(MajorIterator majorStart, MinorIterator minorStart,
MajorDistance majorN, MinorDistance minorN, const T& value)
{
if (majorN==0 || minorN==0) return;
MinorDistance n;
MinorIterator minorFirst = *majorStart;
distance(minorFirst, minorStart, n);
for(MajorIterator major=majorStart; majorN--; major++)
{
MinorIterator minor = *major;
advance(minor, n);
MinorDistance count = minorN;
for(; count--; minor++)
{
*minor = value;
}
}
}
// The above will not work on containers as they currently stand (see
// main below). The only workaround I have been able to come up with is
// to derive a new class from the current containers which provides the
// implicit type conversion that is needed. Something like the following
// may work.
template<class Container>
class better : public Container {
public:
operator Container::const_iterator() const
{
return this->begin();
}
};
// Here is a main() which illustrates the problem.
int main(int argc, char *argv[])
{
// The following is OK.
int a[3][4]; // an array of arrays
fill(a, a[0], 3, 4, 42);
// The following won't compile because *major is a vector<int> and there
// is no way of getting (*major).begin() within the template definition
// such that it will also work for arrays of arrays.
vector<vector<int> > vv; // a vector of vectors
fill(vv.begin(), (*vv.begin()).begin(),
vv.size(), (*vv.begin()).size(), 42);
// The following would be necessary to use the workaround described above.
better<vector<better<vector<int> > > > bvbv; // Ick!
fill(bvbv.begin(), (*bvbv.begin()).begin(),
bvbv.size(), (*bvbv.begin()).size(), 42);
}
Why was this kind of conversion left out of the standard? Or am I missing
something fundamental?
--Dean