Re: Casting references through unions.
Falk Tannh?user wrote:
FWIW, it is even possible to let the compiler deduce the destination
type, letting you write
Foo(ref_convert(e));
However, there are two important drawbacks: It will fail if Foo() is
overloaded/templatised for several parameter types, and it has much more
overhead (dynamic allocation + virtual dispatch, unless somebody comes
up with a better solution).
Another drawback is that such stuff should not be written too early in
the morning - the class lacks a working copy constructor.
Anyway, here is how to do it:
template<typename SrcT> class ref_conv_helper
{
struct wrapper_base
{
virtual ~wrapper_base() {}
virtual void get_src(SrcT&) = 0;
virtual wrapper_base* clone() const = 0;
}; // struct wrapper_base
template<typename DstT> struct wrapper : public wrapper_base
{
DstT dest;
wrapper() : dest() {}
void get_src(SrcT& src)
{
// Check if dest is in range for SrcT?
src = static_cast<SrcT>(dest);
}
wrapper_base* clone() const { return new wrapper(*this); }
}; // struct wrapper
wrapper_base* ptr;
SrcT& src;
public:
explicit ref_conv_helper(SrcT& s) : ptr(0), src(s) {}
ref_conv_helper(ref_conv_helper const& that)
: ptr(that.ptr == 0 ? 0 : that.ptr->clone()),
src(that.src)
{}
template<typename DstT> operator DstT&()
{
wrapper<DstT>* p = new wrapper<DstT>;
ptr = p;
return p->dest;
}
// Without the following, GCC generates compilation errors since
// it tries to instantiate above conversion operator with DstT =
// 'ref_conv_helper const'.
// Comeau doesn't require this (and even warns that this operator
// will not be called for implicit or explicit conversions).
operator ref_conv_helper const&() { return *this; }
Another interesting thing I would like to understand is why said
instantiation takes place with GCC, but not with Comeau. Which one of
the two compilers is right? Maybe both?
~ref_conv_helper()
{
if(ptr != 0)
ptr->get_src(src);
delete ptr;
}
}; // class ref_conv_helper
template<typename SrcT> inline
ref_conv_helper<SrcT> ref_convert(SrcT& src)
{ return ref_conv_helper<SrcT>(src); }
Falk
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]