1

I want to pass Derived class as a template parameter Base<T> class.

When my Derived class is a template and it is very long, my code has minor maintainability and readability problem, e.g.

template<class Derived>class Base{ //library : don't modify me

};
template<template<class>class T1,class T2,class T3>class Derived : //user class
  public Base<Derived<T1,T2,T3>>{

};

I have some cases that Derived has a lot of template and I have to re-type/copy-paste it several times :-

template<template<class>class T1,class T2,class T3>class HyperDatabase : //user class
  public IndexManager<HyperDatabase<T1,T2,T3>>,
  public AwesomeHash<HyperDatabase<T1,T2,T3>,BitShifter>,
  public Allocator<AlloDefault,HyperDatabase<T1,T2,T3>> { // etc...

};

Question

Is there a way to make it more concise?

I dream for something like :-

template<template<class>class T1,class T2,class T3>class Derived : //user class
  public Base<Derived>{

};

OR

template<template<class>class T1,class T2,class T3>class Derived : //user class
  public Base<MEEEEEEE>{

};

My poor solutions

  • Use macro #define MEEEEEEE Derived<T1,T2,T3>.

  • Double inheritance : it is too awkward :-

    template<class T>class Base2:  public Base<T>{};//user class
    template<template<class>class T1,class T2,class T3>class Derived : //user class
      public Base2<Derived<T1,T2,T3>>{
    
    };
    
javaLover
  • 6,347
  • 2
  • 22
  • 67

1 Answers1

1

You can write a variadic crtp combiner:

template <class T, template <class> ...Cs>
struct CrtpCombiner : Cs<T>... {};

Usage:

template<template<class>class T1,class T2,class T3>class 
HyperDatabase : CrtpCombiner<HyperDataBase<T1, T2, T3>, 
IndexManager, BitHash, DefaultAllocator>-
 { // etc...
};

Where BitHash and DefaultAllocator are template aliases (using declarations) that lock down all the template arguments except derived.

Nir Friedman
  • 17,108
  • 2
  • 44
  • 72
  • I have never seen anything like this. I find no interesting result from googling "variadic crtp combiner". May you elaborate it, please? – javaLover May 13 '17 at 01:57
  • I think I would not work so nice if `IndexManager`, `BitHash`, `DefaultAllocator` has different orders of template argument (as in the example). But thank for giving new knowledge. – javaLover May 13 '17 at 02:03
  • They won't have different orders, as I mentioned those have too be aliases that only take one argument. – Nir Friedman May 13 '17 at 02:04
  • Sorry, I didn't read it carefully. I understand now ... this solution would required a bit more work in such complicated situation. – javaLover May 13 '17 at 02:06
  • Well, two one liners, but sure. Probably an alias like DefaultAllocator can be reused anyhow. If you are consistent about putting derived parameter (good idea anyway) first there are fancier things you can do to avoid the aliases. – Nir Friedman May 13 '17 at 02:24
  • Where did other answer go? – Nir Friedman May 13 '17 at 02:24