B
Bolin
Hi all,
A question about smart pointers of constant objects. The problem is to
convert from Ptr<T> to Ptr<const T>. I have look up and seen some
answers to this question, but I guess I am too stupid to understand
and make them work.
E.g. I have read that boost's smart pointers are able to do this
convertion, but the following code doesn't compile (VC++6.0):
--
#include <iostream>
#include <boost/shared_ptr.hpp>
class A
{
int m_i;
public:
A(int i) { m_i = i;}
int getI() const { return m_i;}
};
void foo(boost::shared_ptr<A const> &a)
{
std::cout << a->getI() << std::endl;
}
int main(int argc, char* argv[])
{
boost::shared_ptr<A> a (new A(2));
foo(a);
return 0;
}
--
gives error C2664: Cannot convert from class Ptr<...> to class
Ptr<const...>& .
However, a foo(boost::shared_ptr<A const> a) (without '&') would work.
I have no idea why.
Playing around on my own, it turns out that
--
#include <iostream>
template <class T>
class Ptr
{
T * m_pointer;
public:
Ptr(T *pext) : m_pointer(pext) {};
T* operator->(void) { return m_pointer; }
operator Ptr<const T> & ()
{
return *(static_cast<Ptr<const T>*>(static_cast<void*>(this)));
}
};
struct A
{
typedef double T;
T m_i;
A(T i) { this->setI(i);}
T getI() const { return m_i;}
void setI(T i) { m_i = i;}
};
void foo(Ptr<const A> &a)
{
std::cout << a->getI() << std::endl;
}
int main ()
{
Ptr<A > a = new A(3.14);
foo(a);
return 0;
}
--
would compile. I could live with a yukky double static_cast. But then,
replacing A and foo by
template <class T>
struct AT
{
T m_i;
AT(T i) { this->setI(i);}
T getI() const { return m_i;}
void setI(T i) { m_i = i;}
};
template <class T>
void fooT(Ptr<const AT<T> > &a)
{
std::cout << a->getI() << std::endl;
}
it doesn't work anymore (error C2664).
I would really appreciate if somebody could explain me what is going
on.
So far, the only way I could make things work is having a ConstPtr and
making Ptr derive from ConstPtr, hoping that nobody will ever use a
Ptr<const T>. This last solution is not very pleasing and I am sure
there are better ways, I am just not sure how to do.
Thanks for your time,
Bolin
A question about smart pointers of constant objects. The problem is to
convert from Ptr<T> to Ptr<const T>. I have look up and seen some
answers to this question, but I guess I am too stupid to understand
and make them work.
E.g. I have read that boost's smart pointers are able to do this
convertion, but the following code doesn't compile (VC++6.0):
--
#include <iostream>
#include <boost/shared_ptr.hpp>
class A
{
int m_i;
public:
A(int i) { m_i = i;}
int getI() const { return m_i;}
};
void foo(boost::shared_ptr<A const> &a)
{
std::cout << a->getI() << std::endl;
}
int main(int argc, char* argv[])
{
boost::shared_ptr<A> a (new A(2));
foo(a);
return 0;
}
--
gives error C2664: Cannot convert from class Ptr<...> to class
Ptr<const...>& .
However, a foo(boost::shared_ptr<A const> a) (without '&') would work.
I have no idea why.
Playing around on my own, it turns out that
--
#include <iostream>
template <class T>
class Ptr
{
T * m_pointer;
public:
Ptr(T *pext) : m_pointer(pext) {};
T* operator->(void) { return m_pointer; }
operator Ptr<const T> & ()
{
return *(static_cast<Ptr<const T>*>(static_cast<void*>(this)));
}
};
struct A
{
typedef double T;
T m_i;
A(T i) { this->setI(i);}
T getI() const { return m_i;}
void setI(T i) { m_i = i;}
};
void foo(Ptr<const A> &a)
{
std::cout << a->getI() << std::endl;
}
int main ()
{
Ptr<A > a = new A(3.14);
foo(a);
return 0;
}
--
would compile. I could live with a yukky double static_cast. But then,
replacing A and foo by
template <class T>
struct AT
{
T m_i;
AT(T i) { this->setI(i);}
T getI() const { return m_i;}
void setI(T i) { m_i = i;}
};
template <class T>
void fooT(Ptr<const AT<T> > &a)
{
std::cout << a->getI() << std::endl;
}
it doesn't work anymore (error C2664).
I would really appreciate if somebody could explain me what is going
on.
So far, the only way I could make things work is having a ConstPtr and
making Ptr derive from ConstPtr, hoping that nobody will ever use a
Ptr<const T>. This last solution is not very pleasing and I am sure
there are better ways, I am just not sure how to do.
Thanks for your time,
Bolin