Article View: comp.std.c++
Article #3033An STL helper -- and template and type shenanigans
From: D. Allan Drummond
Date: Thu, 18 Jan 1996 02:05
Date: Thu, 18 Jan 1996 02:05
113 lines
3992 bytes
3992 bytes
In writing an STL helper function, I ran into a snag. The helper function
is used to make a deep copy of a list of pointers, so that the following
code is possible:
#include <list.h>
class A {}
main()
{
list<A*> alist;
// Now add bunches of A*'s to the list...
list<A*> other_alist;
deep_copy( alist, other_alist );
// Now modify contents of other_alist with impunity --
// they're distinct from alist's.
}
Below are the two template functions that do the work.
----------------
// deep_copy requires that class T have
// a copy constructor, and for best use, one that
// makes a deep copy.
template<class Iter, class ContainedType>
void deep_copy( Iter fromB, Iter fromE, Iter toB, Iter toE, ContainedType* )
{
while( (fromB != fromE) && (toB != toE) && *fromB )
*toB++ = new T( **fromB++ );
}
template<class Container>
void deep_copy( Container& from, Container& to )
{
to = from; // expand to make sure TO is as big as FROM.
// should be cheap, if this is really a list of pointers.
Container::value_type type;
deep_copy( from.begin(), from.end(), to.begin(), to.end(), type );
}
-----------------
Note: STL container classes all have a public typedef like this --
typedef T value_type;
The above set of functions will always be run on pointer-lists, where
T is a pointer type.
-----------------
So, the obvious strange item is the ContainedType class in the top template
header. The problem is that Container::value_type is a pointer type, so I
can't say something like *toB = new Container::value_type( **fromB ) --
that would make the rhs a **, which is not the desired *.
The template mechanism has the strange ability to "dereference" types, so
that when I pass a T* to the top function, I can then use the T type
normally.
This seems ugly to me. How can I get access to the type T (not T*) in the
first function, so that I don't have to pass a bogus parameter to some
second function?
( For the casual reader: You must use all template types in the function
arguments. Consider a silly example:
template<class T, class S> void foo( T t ) { S* s = new S; }
How could the compiler figure out what S was from the following?
A a;
foo( a ); )
I really want to write something like this (the following code is
nonsensical but should convey the spirit of the idea):
template<class Container>
void deep_copy( Container& from, Container& to )
{
to = from; // expand to make sure TO is as big as FROM.
// should be cheap, if this is really a list of pointers.
Container::const_iterator f( from.begin() );
Container::iterator t( to.begin );
while( (f != from.end()) && (t != to.end()) && *f )
*t++ = new (*Container::value_type)( **f++ );
}
It seems as though there's no REAL reason to have to split it into two
functions, but the "type dereferencing" is crucial.
Any suggestions? Incidentally, the two-function method works great --
feel free to rip it off with impunity.
Thanks,
Allan
allan.drummond@trilogy.com
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID:
<30FCDA77.69CB@trilogy.com>Path:
arc1-ca.pugleaf.net!in2.uu.net!bounce-backShow Full Headers
Complete Article Headers
From: "D. Allan Drummond" <allan.drummond@trilogy.com> Message-ID: <30FCDA77.69CB@trilogy.com> X-Original-Date: Wed, 17 Jan 1996 05:16:07 -0600 Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back Date: 18 Jan 96 02:05:47 GMT Approved: fjh@cs.mu.oz.au Newsgroups: comp.std.c++ Subject: An STL helper -- and template and type shenanigans Organization: Trilogy X-Mailer: Mozilla 2.0b3 (WinNT; I) Cc: "std-c++@ncar.ucar.edu"@armadillo.trilogy.com X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMP2rQuEDnX0m9pzZAQEAnwGAi32UgLsDQ1YCWkaJOzwu7n3FD9QJVWiz LP1F0BxD27xHyr5pKRzrRu1Hq9p9CP74 =NuWH