2

テンプレートパラメータの基本クラスを取得する方法を見つけようとしています。

次のクラスについて考えてみます。

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

Cが参照(例:Test&)の場合、ptrタイプC&*です。

しかし、Cが参照、ポインター、またはその他のものであるかどうかに関係なく、基本クラスのポインターを取得する必要があります。

  • CTest&の場合、ptrはTest*である必要があります。
  • CTest*の場合、ptrはTest *である必要があります。
  • Cテストの場合、ptrはテスト*などである必要があります。

とにかくCの「基本」クラスを取得して、必要なポインターを作成できるようにすることはできますか?

4

4 に答える 4

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]>::typeですint

于 2012-04-25T20:22:48.300 に答える
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削除し、ポインターを削除します。

于 2012-04-25T20:18:54.023 に答える
2

使ってstd::remove_referenceみませんか?

#include <type_traits>

template <class C>
class Foo
{
    public:
        Foo(){};
        ~Foo(){};
        std::remove_reference<C>::type *ptr;
};
于 2012-04-25T20:18:46.467 に答える
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削除され、型にポインタがなくなるまで再帰的に呼び出されます。

于 2012-04-25T20:26:13.773 に答える