4

Please note this is a question about template syntax only -- not general c++ object oriented, polymorphism design. This example is a fabrication for that purpose

Say I have a base class:

class A: public B
{
...
};

I use it...

A a;
a.DoSomething();

What If I wanted to do something like this, to be able have a compile-time derivation of A, not only from B but from other classes. So that I can use it like this:

A<B> a;                // like class A : public B
a.doSomething();

A<C> ac;              // like class A : public C
ac.DoSomething();

Can I do something like this?

template <typename BASECLASS>
class A : public BASECLASS
{
...
};

Let's assume my constructor had a parameter and I knew that whatever template I use for hte base class had the same signature. If so, this is the *.h file, what do you do with the *.cpp file? Is that legal for initializing the constructor?

A::A(int param) : BASECLASS(param)
{

}

Please note this is a question about template syntax only -- not general c++ object oriented, polymorphism design.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
JasonGenX
  • 4,952
  • 27
  • 106
  • 198

2 Answers2

1

You got the syntax correct in your example. Here is a minimal compilable example.

template <class Base>
class A : public Base {

};

class B {
public:
  void doSomething() {}
};
class C {
public:
  void doSomething() {}
};

int main() {
  A<B> a;                // like class A : public B
  a.doSomething();

  A<C> ac;              // like class A : public C
  ac.doSomething(); 
}
OmnipotentEntity
  • 16,531
  • 6
  • 62
  • 96
  • So this must defined in a single file? no *.h/*.cpp separation? – JasonGenX Dec 20 '13 at 19:25
  • Class B and class C's function defintions can be in the .cpp, but they need to be declared before A. – IdeaHat Dec 20 '13 at 19:26
  • 1
    Like all templates, the entire function body has to be available at compile time, rather than link time. So A needs to be in headers only. But B and C can be done normally. – OmnipotentEntity Dec 20 '13 at 19:26
  • what if A had a constructor that required a parameter? and classes B and C also had similar constructors? can you make the A constructor in a separate *.cpp file? – JasonGenX Dec 20 '13 at 19:26
  • 1
    @MadScienceDreams, correct me if I'm wrong, but AFAIK B and C don't need to be declared before A? The example given compiles just fine. – OmnipotentEntity Dec 20 '13 at 19:29
  • @OmnipotentEntity Sorry, before the instantiation of A is the right way to say it, my bad :-P – IdeaHat Dec 20 '13 at 19:30
0

Actually, with C++11, this became even more easy:

template <typename T>
class A: public T {
public:
    template <typename... Args>
    explicit A(Args&&... args): T(std::forward<Args>(args)...) {}

};

This use of variadic template arguments (typename...) combined with reference collapsing (&& in a template deduces to the best reference match possible) and std::forward allows for perfect forwarding; as if the "layer" of A's constructor was transparent.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722