Re: cast from list<T> to list<const T>

Discussion in 'C++' started by Nick Hounsome, Apr 1, 2004.

  1. "Jonathan Turkanis" <> wrote in message
    news:c4fl16$2dma64$-berlin.de...
    > "Alexander Malkis" <-sb.de> wrote in
    > message news:c4fk8v$1a3kv$-saarland.de...
    > > //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!
    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.
    Nick Hounsome, Apr 1, 2004
    #1
    1. Advertising

  2. Nick Hounsome

    Siemel Naran Guest

    "Nick Hounsome" <> wrote in message news:DhXac.7585

    > 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.


    This should work, but seems it may take more effort than a smart pointer as
    you have to create iterator classes, fix all functions like push_back(),
    back(), etc. And it doesn't generalize to all containers either; list and
    deque have push_front, vector has reserve, list has sort etc. Furthermore,
    it leads to an extra instantiation of Collection<list<T*>>.
    Siemel Naran, Apr 1, 2004
    #2
    1. Advertising

  3. "Nick Hounsome" <> wrote in message
    news:DhXac.7585$...
    >
    > "Jonathan Turkanis" <> wrote in message
    > news:c4fl16$2dma64$-berlin.de...
    > > "Alexander Malkis" <-sb.de> wrote

    in
    > > message news:c4fk8v$1a3kv$-saarland.de...
    > > > //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.
    >
    >
    >
    Jonathan Turkanis, Apr 1, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Malkis

    How to cast from list<T*> to list<const T*>

    Alexander Malkis, Apr 1, 2004, in forum: C++
    Replies:
    2
    Views:
    412
    Alexander Malkis
    Apr 2, 2004
  2. Siemel Naran
    Replies:
    0
    Views:
    352
    Siemel Naran
    Apr 1, 2004
  3. Replies:
    11
    Views:
    1,099
  4. Javier
    Replies:
    2
    Views:
    558
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,110
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page