Andrew
Andrew

Reputation: 986

c++ class member variable of the nested template type

I would like to create a templated class (C2), using as a template a class which is also templated (C1). Moreover in C2 create a variable of the same type, which was used as template of the class C1.

template <typename Ttype>
class C1{
public:
    Ttype var;
}

template<class T> //class T always templated
class C2{
public:
    T x;
//  ? y; << variable of template type of the class T
}

int main()
{
    C1<int>  instanceInt;
    C1<long> instanceLong;
    
    C2<C1<int>> foo; //C2.y should be int
}

My initial implementation of the class C2 was as follows, however it results in error: identifier "Ttype" is undefined. Why doesn't compiler see the Ttype?

template <template <class Ttype> class Tparam>
class C2 {

public:
    Tparam<Ttype> x;
    const Ttype y;
};

So my working, but not so nice solution is using a typedef.

template <typename Ttype>
class C1{
public:
    typedef Ttype Ctype
    Ttype var;
}

template<class T>
class C2{
public:
    typedef typename T::Ctype Ttype;
    T x;
    Ttype y;
}

I expect that there should be a better implementation of the same feature. Is there?

Upvotes: 1

Views: 202

Answers (2)

max66
max66

Reputation: 66240

You can use template specialization

template <typename>
class C2;

template <template <typename> class C, typename T>
class C2<C<T>>
 {
   public: 
      C<T> x;
      T    y;
 };

or you can also develop a custom type trait to extract a template argument from a type

template <typename>
struct get_tmpl_param;

template <template <typename> class C, typename T>
struct get_tmpl_param<C<T>>
 { using type = T; };

template <typename T>
using get_tmpl_param_t = typename get_tmpl_param<T>::type;

so your class C2 (without specialization) can be

template <typename T>
class C2
 {
   public:
      T                    x;
      get_tmpl_param_t<T>  y;
 };
  

Upvotes: 1

b00rt00s
b00rt00s

Reputation: 112

The second approach could be fixed, however, the third is not bad either.

template <typename Ttype>
class C1
{
public:
    Ttype var;
};

template<template <class Ttype> class Tparam, typename T>
class C2
{
public:
    Tparam<T> x;
    T y;
};

void foo()
{
    C2<C1,int> bar;
}

Upvotes: 1

Related Questions