"Nick Hounsome" <> wrote in message
news

hXac.7585$...
>
> "Jonathan Turkanis" <> wrote in message
> news:c4fl16$2dma64$...
> > "Alexander Malkis" <> wrote
in
> > message news:c4fk8v$1a3kv$...
> > > //Consider:
> > > class A { /*...*/ };
> > >
> > > template<class T> class list {/*... */ };
> > >
> > > void f(const list<const A*> lst) { /*...doesn't change the
> > arg...*/ }
> > >
> >
> > list<const A*> and list<A*> are unrelated types. Neither is
> > convertible to the other. If you have a list<A*> mylist and you
want a
> > list<const A*>, you can do this:
> >
> > list<const A*> copy(mylist.begin(), mylist.end());
> >
> > Jonathan
>
> You missed the fact that f doesn't even take a reference!
Huh? I did miss the fact that the OP wasn't talking about std::list,
but don't see how the fact that f doesn't take a reference is
relevant. I was just addressing the issue of convertibility. In
particular, standard container templates don't have converting
constructors which accept different specializations of the same
template. They achieve the same effect with greater generality by
allowing construction from iterator ranges.
That was my point. Now I see the template was a user defined template;
in that case, you have to use whatever conversions are provided by
that template. In particular, list<const A*> might have a constructor
accepting a list<A*>, and no constructors taking iterator ranges.
Jonathan
> so
>
> f( list<const A*>(lst.begin(),lst.end()) ) ;
>
> is as efficient as it could possibly be anyway.
>
> On a more helpful note I would suggest that f should be templateized
> as
>
> template <class Collection> void f(const Collection& c) .....
>
> Then create a template wrapper to make any collection of X* appear
as a
> collection of const X*
> and pass this to f.
>
> If the functions only treat the list as a sequence then use a
similar
> approach but with
> begin and end iterators instead - that way there are less functions
to
> implement in the wrapper.
>
>
>