Purpose and craziness aside, is there a way to achieve this in C++?
template <typename P>
void Q void_cast(P Q *p) const
{
return static_cast<P Q *>(p);
}
I'm effectively trying to cast a pointer to a void
pointer type whilst keeping any const
, restrict
and other qualifiers (denoted by Q
).
I was under the impression there was stuff 开发者_StackOverflowin the C++ standard library (or less desirably, in Boost), that allowed you to "tweak" properties of types, with finer granularity than say const_cast
or static_cast
.
So, you want const X*
-> const void*
, volatile X*
-> volatile void*
, etc.
You can do this with a set of overloads:
template<typename P>
void* void_cast(P* p)
{
return p;
}
template<typename P>
void const* void_cast(P const* p)
{
return p;
}
template<typename P>
void volatile* void_cast(P volatile* p)
{
return p;
}
template<typename P>
void const volatile* void_cast(P const volatile* p)
{
return p;
}
The new type traits are things like add_const
, add_volatile
, remove_const
and remove_volatile
. They work for transforming the cv-qualifiers of a type in a known way, not for applying the cv-qualifiers of one type to another.
In the boost type traits lib are some tools to remove qulifiers
http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/index.html
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);
精彩评论