template<class From>
typename copy_rpcv<void, From*>::type void_cast(From *p) {
return p; // implicit conversion works
}
With a little TMP utility:
// "copy ref/pointer/const/volatile"
template<class To, class From>
struct copy_rpcv {
typedef To type;
};
template<class To, class From> struct copy_rpcv<To, From& > { typedef typename copy_rpcv<To, From>::type& type; };
template<class To, class From> struct copy_rpcv<To, From* > { typedef typename copy_rpcv<To, From>::type* type; };
template<class To, class From> struct copy_rpcv<To, From const > { typedef typename copy_rpcv<To, From>::type const type; };
template<class To, class From> struct copy_rpcv<To, From volatile> { typedef typename copy_rpcv<To, From>::type volatile type; };
You'd have to add another case for the restrict specifier; it probably would work just fine, but I don't know how it, as a non-standard feature in 03 (is it in 0x?), interacts:
template<class To, class From> struct copy_rpcv<To, From* restrict> { typedef typename copy_rpcv<To, From>::type* restrict type; };
My solution differs from Anthony's in preserving "nested" type info:
int *const *const p = 0;
void *const *const v = void_cast(p);