Cast vector<foo*> to vector<const foo*>?

Discussion in 'C++' started by Joseph Turian, Jan 26, 2006.

  1. Some function requires a vector<const foo*> argument.
    How can I cast a vector<foo*> to vector<const foo*>?

    Thanks!

    Joseph
     
    Joseph Turian, Jan 26, 2006
    #1
    1. Advertising

  2. Joseph Turian

    Ian Collins Guest

    Joseph Turian wrote:
    > Some function requires a vector<const foo*> argument.
    > How can I cast a vector<foo*> to vector<const foo*>?
    >

    You can't; they are completely different types.

    --
    Ian Collins.
     
    Ian Collins, Jan 26, 2006
    #2
    1. Advertising

  3. Ian Collins wrote:
    > > How can I cast a vector<foo*> to vector<const foo*>?

    > You can't; they are completely different types.


    Care to edify me why?
    At first blush, they seem quite similar.

    Joseph
     
    Joseph Turian, Jan 26, 2006
    #3
  4. Joseph Turian

    Ian Collins Guest

    Joseph Turian wrote:
    > Ian Collins wrote:
    >
    >>>How can I cast a vector<foo*> to vector<const foo*>?

    >>
    >>You can't; they are completely different types.

    >
    >
    > Care to edify me why?
    > At first blush, they seem quite similar.
    >

    An instantiation of a class template is a unique class. Don't be fooled
    by the template type, it my look similar to you, but it's apples and
    oranges to the compiler. foo* and const foo* are different types.

    --
    Ian Collins.
     
    Ian Collins, Jan 26, 2006
    #4
  5. Joseph Turian

    John Carson Guest

    "Joseph Turian" <> wrote in message
    news:
    > Ian Collins wrote:
    >>> How can I cast a vector<foo*> to vector<const foo*>?

    >> You can't; they are completely different types.

    >
    > Care to edify me why?
    > At first blush, they seem quite similar.
    >
    > Joseph


    To add to what Ian has said,

    foo * and const foo * are different types but are nevertheless similar
    enough that you can use const_cast to cast between them. Where two types are
    used as template arguments, however, the similarity of the types is
    irrevant. Consider:

    template<class T>
    class Test
    {
    T t;
    };

    template<>
    class Test<const int>
    {
    char array[1000];
    };

    Thus Test<const int> contains an array of chars, whereas Test<int> contains
    a single int.

    #include <iostream>
    using namespace std;

    int main()
    {
    Test<int> t1;
    Test<const int> t2;
    cout << sizeof(t1) << endl; // gives 4
    cout << sizeof(t2) << endl; // gives 1000
    return 0;
    }

    In reality vector<foo *> and vector<const foo *> may hardly differ at
    all --- in particular, they may have the same size. However, the possibility
    of explicit template specialization means that they could differ
    spectacularly, hence the reluctance of the compiler to allow conversion.


    --
    John Carson
     
    John Carson, Jan 26, 2006
    #5
  6. Joseph Turian

    Ben Pope Guest

    Joseph Turian wrote:
    > Some function requires a vector<const foo*> argument.
    > How can I cast a vector<foo*> to vector<const foo*>?


    As said, you can't cast.

    You'll have to copy each element.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Jan 26, 2006
    #6
  7. Joseph Turian

    Earl Purple Guest

    Ben Pope wrote:
    > Joseph Turian wrote:
    > > Some function requires a vector<const foo*> argument.
    > > How can I cast a vector<foo*> to vector<const foo*>?

    >
    > As said, you can't cast.
    >
    > You'll have to copy each element.


    You have to copy each element if you want a vector< const Foo * >

    However if all you want to do is pass a reference to your vector and
    ensure that none of the Foo objects are modified, you can use an
    adapter,

    template < typename T >
    vector_const_adapter
    {
    typedef std::vector< T * > vec_type;

    const vec_type * itsVecRef;

    public:

    typedef typename vec_type::size_type size_type;

    vector_const_adapter() : itsVecRef( 0 ) {}

    vector_const_adapter( const vec_type & vecRef )
    : itsVecRef( &vecRef )
    {
    }


    const T* operator[] ( size_type idx ) const
    {
    return (*itsVecRef)[ idx ];
    }

    bool empty() const;
    size_type size() const;
    const T* const * begin() const;
    const T* const * end() const;
    };

    and I'll leave it up to you to implement the functions empty() size(),
    begin() and end()

    Now all you have to do is pass around vector_const_adapter<Foo>. Note I
    used a member pointer so that vector_const_adapter can have a default
    constructor and be assignable. If you don't want these features use a
    member reference.
     
    Earl Purple, Jan 26, 2006
    #7
  8. "Joseph Turian" <> wrote in message
    news:...
    > Ian Collins wrote:
    >> > How can I cast a vector<foo*> to vector<const foo*>?

    >> You can't; they are completely different types.


    > Care to edify me why?
    > At first blush, they seem quite similar.


    Here is one reason:

    void append(vector<const foo*>& v, const foo* p)
    {
    v.push_back(p);
    }

    const foo f;
    const foo* p = &f;
    vector<foo*> v;
    append(v, p);

    By casting v to vector<const foo*>&, you have managed to put a const foo*
    value into a vector<foo*>. Now, you can execute

    v.last()->munge();

    where munge is a member of class foo that modifies its object. By doing so,
    you have modified a const foo object.
     
    Andrew Koenig, Jan 26, 2006
    #8
  9. Joseph Turian

    Earl Purple Guest

    Andrew Koenig wrote:
    > > Care to edify me why?
    > > At first blush, they seem quite similar.

    >
    > Here is one reason:
    >
    > void append(vector<const foo*>& v, const foo* p)
    > {
    > v.push_back(p);
    > }
    >
    > const foo f;
    > const foo* p = &f;
    > vector<foo*> v;
    > append(v, p);
    >
    > By casting v to vector<const foo*>&, you have managed to put a const foo*
    > value into a vector<foo*>. Now, you can execute
    >
    > v.last()->munge();
    >
    > where munge is a member of class foo that modifies its object. By doing so,
    > you have modified a const foo object.


    Something you couldn't do with my adapter as you cannot modify the
    vector either thus you can't push anything onto it.
     
    Earl Purple, Jan 27, 2006
    #9
    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. Replies:
    3
    Views:
    394
    John Roth
    Jul 29, 2005
  2. Javier
    Replies:
    2
    Views:
    584
    James Kanze
    Sep 4, 2007
  3. .rhavin grobert

    vector: Foo[5] == ((foo*)Foo) + 5 ?

    .rhavin grobert, Sep 23, 2008, in forum: C++
    Replies:
    4
    Views:
    409
    JaredGrubb
    Sep 24, 2008
  4. Replies:
    2
    Views:
    545
    Andrew Koenig
    Feb 9, 2009
  5. Ralf Goertz

    const foo * and const foo &

    Ralf Goertz, Jan 26, 2011, in forum: C++
    Replies:
    3
    Views:
    529
    Ralf Goertz
    Jan 27, 2011
Loading...

Share This Page