c++templatestypedef

"typedefing" base class in templates


While doing some simple metaprogramming, I encountered the following annoying syntax issue.

I need to derive some templated class from another templated class with a rather non-trivial and long list of template parameters. I also have to address an inner type that has been defined in the base class from inside the derived class definition.

In distilled form, it looks something like this:

template<int X, int Y, int Z>
class A : public B<X-1,Y-1,Z-1>
{
  typedef B<X-1,Y-1,Z-1>::SomeType MyType;
};

The long base class definition (B<X-1,Y-1,Z-1>) is typed more than once. In usual case, I typedef such class and use its simple "typedef-ed" alias. However, in case of inheritance, there's no place to do it before the inheritance statement, and one must use it at least once in its full form, which kind of defies the typedef purpose.

Is there any syntax trick that can allow me to typedef the base class only once? The default template parameter will not work for a template pack and for template specifications in general, I think.

UPD: typedefing the inherited templated base class with base ctors call


Solution

  • You can make it like

    template <int X, int Y, int Z>
    struct B {
      typedef int SomeType;
    };
    
    template <int X, int Y, int Z, typename B = B<X - 1, Y - 1, Z - 1>>
    class A : public B {
      using MyType = typename B::SomeType;
      typedef typename B::SomeType MyType2;
    };
    
    int main() { A<1, 2, 3> a; }
    

    With the hidden 4th template parameter

    namespace detail {
    
    template <int X, int Y, int Z, typename B = B<X - 1, Y - 1, Z - 1>>
    class A : public B {
      using MyType = typename B::SomeType;
      typedef typename B::SomeType MyType2;
    };
    
    }  // namespace detail
    
    template <int X, int Y, int Z>
    using A = detail::A<X, Y, Z>;
    

    Or

    namespace detail {
    
    template <typename B>
    class A : public B {
      using MyType = typename B::SomeType;
      typedef typename B::SomeType MyType2;
    };
    
    }  // namespace detail
    
    template <int X, int Y, int Z>
    using A = detail::A<B<X - 1, Y - 1, Z - 1>>;