🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #3033

An STL helper -- and template and type shenanigans

#3033
From: D. Allan Drummond
Date: Thu, 18 Jan 1996 02:05
113 lines
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-back

Show 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