Re: Constness with standard containters of pointers
Javier wrote:
Hello,
I have some cuestions about constness with standard containers and
pointers.
Supose I have a list of pointers to some class B:
std::list< B * > > list;
I have readed that constness in std::list is the same that it is in C
arrays (const std::list makes const both the list and its content):
const std::list< B * > > constList;
I can't do:
constList->push_back(x);
But, is it still possible to call any non-const member funcion of B?:
void B::nonConstMemberFuncion();
As in:
constList.begin()->nonConstMemberFuncion();
a) It is possible. I don't want the user to add elements nor modify
any of the list. Which is the correct way of doing this?
const std::list< const B * const > > constList;
const std::list< const B * > constList;
b) It is not possible. Then, I suppose that the next sentences are the
same:
const std::list < B > constList;
const std::list < const B > constList;
If I have the next class:
class A {
public:
std::list< B * > & list() { return m_list; };
private:
std::list< B * > m_list;
};
How I add a const version for A::list()?
Your problem is that the list contains B* object and making those const
(e.g. by refering to the list via a const reference) does not make the
pointees const. You could fix that using a smart pointer that forwards
constness:
template < typename T >
class const_forwarding_ptr {
T * the_ptr;
public:
const_forwarding_ptr ( T * ptr )
: the_ptr ( ptr )
{}
T & operator* ( void ) {
return ( *the_ptr );
}
T const & operator* ( void ) const {
return ( *the_ptr );
}
T * operator-> ( void ) {
return ( the_ptr );
}
T const * operator-> ( void ) const {
return ( the_ptr );
}
operator T * ( void ) {
return ( the_ptr );
}
operator T const * ( void ) const {
return ( the_ptr );
}
};
#include <list>
int main ( void ) {
std::list< const_forwarding_ptr< int > > the_list;
int * i_ptr = new int ( 5 );
the_list.push_back( i_ptr );
*(*(the_list.begin())) = 6;
std::list< const_forwarding_ptr< int > > const & c_ref = the_list;
// the following line does not compile:
// *(*(c_ref.begin())) = 5;
}
What about if I have a smart_pointer instead of a C pointer?
const std::list< boost::shared_ptr< B > > constList =
something();
constList.begin()->nonConstMemberFunction();
Depends on the smart pointer. With regard to shared_ptr from C++0X, it does
not forward constness to the pointee but acts similar to a raw pointer.
Best
Kai-Uwe Bux