Derive a class name from another class name in template

107 views Asked by At

In order to use a library, I need to use different classes that have the same base name. I.e.

MyClass
MyClassImpl
PreMyClass

And so on. in order to use them with template I need pass all these class names.

template <typename T, typename TImpl, typename PreT>
class ClassThatUsesAllTheseObjects
{
  public:
  ClassThatUsesAllTheseObjects();
  private:
  T myClass;
  TImpl myClassImpl;
  PreT myPreClass;
};

It's possibile to obtain the same result giving only the principal MyClass as template argument, building other names when needed?

2

There are 2 answers

0
Ami Tavory On BEST ANSWER

Am not sure of the settings in your question, but in some cases, you might want to do something like the trait mechanism.

Suppose you write a concrete MyClass, and others like it. For each group of concrete classes, you do something like:

// This is common
template <typename T>
struct foo_traits
{

};

// This is for each set of concrete classes
template<>
struct foo_traits<MyClass>
{
   using Impl = MyClassImpl;
   using Pre = PreMyClass; 
};

...

Then you use the traits class like this:

template <
    typename T, 
    class Impl = typename foo_traits<T>::Impl,
    class Pre = typename foo_traits<T>::Pre>
class ClassThatUsesAllTheseObjects
{
  public:
  ClassThatUsesAllTheseObjects();
  private:
  T myClass;
  Impl myClassImpl;
  Pre myPreClass;
};

This allows you to explain what are the "natural friends" of your principal concrete classes.

1
marom On

I can think of two options:

  1. Use a tag to make the difference. So you would have e.g. a template <class T> myClass, a struct impl_t{}, struct pre_t{}, struct base_t{} and then use gthem in this way:

code:

myClass<base_t> ; // instead of plain MyClass
myClass<impl_t> ;// instead of plain MyClassImpl
myClass<pre_t> ; // instead of myPreClass

Template specialization should make their definition easy/possible.

  1. traits, but there is already an answer on that side :-)