Derive a class name from another class name in template

98 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 best solutions below

0
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
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 :-)