如何从T,T& T获得T *或T *模板参数

时间:2012-04-25 20:11:20

标签: c++ templates pointers reference

我试图找到一种方法来获取模板参数的基类。

考虑以下课程:

template <class C>
class Foo
{
    public:
        Foo(){};
        ~Foo(){};
        C* ptr;
};

如果 C 是参考(例如测试&amp; ),则 ptr 是C&amp; *

类型

但我需要得到一个指针基类,无论C是引用,指针还是其他任何东西。

  • 如果 C 测试&amp; ,那么 ptr 需要测试*
  • 如果 C 测试* ,那么 ptr 需要测试*
  • 如果 C 测试,则 ptr 需要测试* 等。

有没有得到C的“基础”类,所以我可以创建我需要的指针?

4 个答案:

答案 0 :(得分:8)

如果确实需要底层元素类型,可以使用删除类型操作特征的递归应用程序:

#include <type_traits>

// precv = pointer, reference, extents, const, and volatile
template <typename T>
struct remove_precv
{
    typedef typename std::remove_pointer<
            typename std::remove_reference<
            typename std::remove_all_extents<
            typename std::remove_cv<T>::type>::type>::type>::type type;
};

template <typename T, typename U>
struct element_type_impl
{
    typedef typename element_type_impl<
            typename remove_precv<T>::type, T>::type type;
};

template <typename T>
struct element_type_impl<T, T>
{
    typedef T type;
};

template <typename T>
struct element_type
{
    struct null_type { };
    typedef typename element_type_impl<T, null_type>::type type;
};

例如,element_type<int***[42]>::typeint

答案 1 :(得分:3)

这样做:

#include <type_traits>

template <typename T>
class Foo
{
    typedef typename std::remove_pointer<typename std::decay<T>::type>::type C;
    // ...
};

decay删除了引用和CV资格,remove_pointer删除了指针。

答案 2 :(得分:2)

如何使用std::remove_reference

#include <type_traits>

template <class C>
class Foo
{
    public:
        Foo(){};
        ~Foo(){};
        std::remove_reference<C>::type *ptr;
};

答案 3 :(得分:2)

您可以使用一些模板元编程来完成此操作,例如:

#include <cassert>
#include <typeinfo>

template <typename T>
struct unpoint {
  typedef T type;
};

template <typename T>
struct unpoint<T*> {
  typedef typename unpoint<T>::type type;
};

int main() {
  int *a;
  int **b;
  int ***c;
  int ****d;

  const std::type_info& t1=typeid(unpoint<decltype(a)>::type);
  const std::type_info& t2=typeid(unpoint<decltype(b)>::type);
  const std::type_info& t3=typeid(unpoint<decltype(c)>::type);
  const std::type_info& t4=typeid(unpoint<decltype(d)>::type);
  assert(t1 == t2);
  assert(t1 == t3);
  assert(t1 == t4);
}

unpoint的特化除去指针并递归调用自身,直到类型中没有指针为止。