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

J

Joseph Turian

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

Thanks!

Joseph
 
I

Ian Collins

Joseph said:
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.
 
I

Ian Collins

Joseph said:
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.
 
J

John Carson

Joseph Turian said:
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.
 
B

Ben Pope

Joseph said:
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
 
E

Earl Purple

Ben said:
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.
 
A

Andrew Koenig

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

Earl Purple

Andrew said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top