1

In the below code, I want to replace "something" with something that will allow me to declare the type of 'f' as the second parameter passed in C (while passing C to M's template), i.e., float here.

#include<iostream>
using namespace std;
template<class A, class B>
class C{
    public :
        A a;
        B b;
};
template<class D>
class M{
    public :
        decltype(D::<something>) f;  //!!!!!!!!!!!!!!!!
        void show(){cout<<f;}
};
int main(){
    M<C<int,float>> m;
    m.show();
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
Jeevesh Juneja
  • 212
  • 2
  • 9

2 Answers2

3

You can do this with some trickery.

template<typename> class M; // leave undefined
template<template<typename, typename> D, 
         typename One,
         typename Two>
 class M<D<One, Two>> { // a specialisation
     Two f;
 };

Now you can pass to M a class that has exactly two template parameters (sich as C<int, float>). If you pass something else (e.g. int) there will be an error.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
2

What about a template taking a template?

With the following line you can declare a template taking a template and have the latter's template arguments types named:

template<
template<typename, typename> class D, 
          typename A, typename B>

With this notation you are saying that D is a is a template parameter which is itself in turn a template and A and B are the types that it takes. Now you can refer to the first and second template parameter of D with the names A and B.


using namespace std;
template<class A, class B>
class C{
    public :
        A a;
        B b;
};
template<template<typename, typename> class T, typename A, typename B>
class M{
    public :
        B f;  //!!!!!!!!!!!!!!!!
        void show(){cout<<f;}
};
int main(){
    M<C, int, float> m;
    m.show();
}

For more info check this answer out.

Davide Spataro
  • 7,319
  • 1
  • 24
  • 36