开发者

Change only parts of a type in a C++ template

开发者 https://www.devze.com 2023-01-18 12:05 出处:网络
Purpose and craziness aside, is there a way to achieve this in C++? template <typename P> void Q void_cast(P Q *p) const

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消