Home > Net >  How to define template template types with inheritance in C 11
How to define template template types with inheritance in C 11

Time:01-27

I would like to define a derived class that has a template template type for a templated base class. Is this possible, and if so what is the syntax? I have tried a lot of things without success. Please consider this code:

#include <iostream>

template <typename U>
struct Wrapper {};

template <typename U>
struct Base {};

// This Works, define a template template type class
template<class>
struct Other;
template<template<typename T> typename W, typename T>
struct Other<W<T>> {};

// How do I define this?
template<template<typename T> typename W, typename T>
struct Derived : public Base<W<T>> {};

using namespace std;

int main()
{
    Wrapper<float> w;
    Base<int> b;
    Other<Wrapper<int>> o;
    Derived<Wrapper<int>> d;  // fails to compile
    return 0;
}

Why: I have existing/working code that has Derived<U> where U is a wrapped class W<T>. Specifying Derived<W<T>> in the definition using a template template type was unnecessary; Derived<U> is sufficient. Both W and T can be many different concrete types, but T will always have a statically available method that I now need access to from within Derived scope.

I am currently and woefully limited to C 11.

CodePudding user response:

Often, things get much simpler if you realize that, for most regards, an instantiation of a class template is just a type like any other. And confusing types with templates is also the source of your error.

Wrapper<int> is a type. The first argument for the Derived template is a template, not a type.

Other is a template that has a single type argument. It has a partial specialization for the case that this type is an instantiation of W.

Derived is a template that has two arguments. The first is a template argument, the second is a type. An instantiation is, for example: Derived<W,int>.

If you want to make Derived a template with a single type argument, with a partial specialization for the case that this type is an instantiation of Wrapper, then you need to do the same as you did for Other: A base template with a single type argument and a specialization, eg:

template<class> struct Derived;

template<template<typename T> typename W, typename T> 
struct Derived<W<T>> : public Base<W<T>> {};

The second line is the partial specialization. It does not change the fact that Derived has one type argument. It only makes Derived<W<T>> match this specialization no matter what T is.

  • Related