🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

5 total messages Started by D. Allan Drummond Thu, 18 Jan 1996 02:05
An STL helper -- and template and type shenanigans
#3033
Author: 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. ]
Re: An STL helper -- and template and type shenanigans
#3038
Author: David Byrden
Date: Thu, 18 Jan 1996 09:29
33 lines
1556 bytes
Allan;.

Can't see a way around your problem. Seem to remember the HP STL doing 
similar things. Why worry, anyway? An optimising compiler will reduce the 
cost of the bogus parameter to near zero.


>>  to = from;

What happens to the original T objects that 'to' was tracking?


>>  void deep_copy( Iter fromB, Iter fromE, Iter toB, Iter toE, 
>>    ContainedType* )

The fourth parameter is redundant; the size of the range to be copied is 
already specified by the first 2 parameters.



>> while( (fromB != fromE) && (toB != toE) && *fromB )

Not sure about this. It assumes that 'from' can contain some NULL 
pointers, but that they are guaranteed to be together in a block at the 
upper end of it.



   David Byrden
---
[ 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. ]
Re: An STL helper -- and template and type shenanigans
#3096
Author: Pulkkinen Esa
Date: Tue, 23 Jan 1996 16:07
58 lines
2481 bytes
In article <30FCDA77.69CB@trilogy.com>,
D. Allan Drummond <allan.drummond@trilogy.com> wrote:
[an example and discussion about type dereferencing removed]
>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.

Well, you can generalize the type deferencing scheme using a partial
specialization:

template <class T> class type_dereferencer
{
};

template <class T>
class type_dereferencer<T*>
{
public:
  typedef T base_type;
};

Of course you would also have to specialize for user-defined
pointer types and STL iterators.

Now you can use
type_dereferencer<Container::value_type>::base_type in place of 
(*Container::value_type) in your example.

And if typedef templates were allowed, you could use a slightly better
syntax:

template <class T>
typedef type_dereferencer<T>::base_type type_dereference;
--
   Esa Pulkkinen                        | C++ programmers do it virtually
   E-Mail:  esap@cs.tut.fi              | everywhere with a class, resulting
   WWW   :  http://www.cs.tut.fi/~esap/ | in multiple inheritance.




[ 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. ]
Re: An STL helper -- and template and type shenanigans
#3133
Author: Fergus Henderson
Date: Mon, 29 Jan 1996 18:50
26 lines
1600 bytes
esap@cs.tut.fi (Pulkkinen Esa) writes:

>template <class T>
>class type_dereferencer<T*>
>{
>public:
>  typedef T base_type;
>};
[...]
>And if typedef templates were allowed, you could use a slightly better
>syntax:
>
>template <class T>
>typedef type_dereferencer<T>::base_type type_dereference;

Can someone please remind me why we decided not to allow typedef templates?
It certainly seems like a bad idea to force everyone to use this silly
obfuscation for what is obviously a common need.

--
Fergus Henderson             	WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au              	PGP: finger fjh@128.250.37.3
---
[ 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. ]
Re: An STL helper -- and template and type shenanigans
#3222
Author: Doug Morgan
Date: Sat, 03 Feb 1996 06:45
25 lines
1860 bytes
In article <9601281244.8175@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
(Fergus Henderson) writes:
> ..
> Can someone please remind me why we decided not to allow typedef templates?
> It certainly seems like a bad idea to force everyone to use this silly
> obfuscation for what is obviously a common need.

D&E says: "The extension is technically trivial, but I'm not sure how
wise it would be to introduce yet another renaming feature."

I have no idea why the committee might have killed typedef templates,
but I doubt that any reasoning used had more than the zero technical
merit of the above.

Doug
----------
Doug Morgan         TEL: (408) 744-3510 Booz-Allen & Hamilton 
doug@ads.com (UNIX) FAX: (408) 744-3565 385 Moffett Park Drive
morgan_doug@bah.com (MS-Mail)           Suite 110             
					Sunnyvale, CA 94089
----------
---
[ 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. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads