Re: Treating Foo<T>* as Foo<const T>*
On 18 Jun., 17:31, Edward Rosten <edward.ros...@gmail.com> wrote:
On Jun 17, 2:34 pm, Ulrich Eckhardt <eckha...@satorlaser.com> wrote:
Take a look at boost::shared_ptr. Those behave just like raw pointers, i.e.
a shared_ptr<Foo> will be implicitly converted to a shared_ptr<Foo const>
You are mistaken. The conversion to a const version of the same type
is different from conversions to other types. By way of illustration,
this code snippet does not compile:
#include <tr1/memory>
using namespace std::tr1;
template<class C> void func1(const shared_ptr<C const>&);
template<class C> void func2(const C*);
int main()
{
shared_ptr<int> i1;
int* i2;
func1(i1); //Not OK
func2(i2); //OK -- and does the right thing.
func1(shared_ptr<const int>(i1)); //Yuck!
}
If func simply accepted a const C* instead, then it would compile just
fine. One can make it compile, but the syntactic overhead is just
plain nasty.
I don't think that the current state is a
inherent defect in C++ templates. As usual,
if you want to realize a special T -> U relation,
you need to implement that, e.g. you could
use inheritance to simulate the same effect:
template<class T>
struct shared_ptr;
template<class T>
struct shared_ptr<const T> {
... //
};
template<class T>
struct shared_ptr : shared_ptr<const T> {
... //
};
This way you program above will be well-formed and
it will also accept the following conversions:
shared_ptr<int>* pi2 = 0;
shared_ptr<const int>* cpi2 = pi2;
shared_ptr<int> i1;
shared_ptr<const int> ci1 = i1;
Above is just a sketch, here are some details
for a possible implementation which ensures
that the member data is hold only once:
template<class T>
class shared_ptr;
template<class T>
class shared_ptr<const T> {
friend class shared_ptr<T>;
T* ptr;
public:
shared_ptr(const T* ptr = 0) : ptr(const_cast<T*>(ptr)) {}
const T* get() const { return this->ptr; }
// ...
};
template<class T>
class shared_ptr : public shared_ptr<const T> {
public:
shared_ptr(T* p = 0) : shared_ptr<const T>(p) {}
T* get() const { return this->ptr; }
// ...
};
Maybe there are other ways to realize the
same effect - I never had the need for such
a relation.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]