Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template Child Class Overriding a Parent Class's Virtual Function

The below code compiles with gcc v4.3.3 and the templated child class seems to be overriding a virtual function in the parent, but doesn't that break the rule that you cannot have a virtual template function? Or is something else happening that I don't understand?

class BaseClass
{
public:
  virtual void Func(int var)
  {
    std::cout<<"Base int "<<var<<std::endl;
  }

  virtual void Func(double var)
  {
    std::cout<<"Base double "<<var<<std::endl;
  }
};

template <class TT>
class TemplateClass : public BaseClass
{
public:
  using BaseClass::Func;
  virtual void Func(TT var)
  {
    std::cout<<"Child TT "<<var<<std::endl;
  }
};

int main(int argc, char **argv)
{
  BaseClass a;
  TemplateClass<int> b;
  BaseClass *c = new TemplateClass<int>;

  int intVar = 3;
  double doubleVar = 5.5;

  a.Func(intVar);
  a.Func(doubleVar);
  b.Func(intVar);
  b.Func(doubleVar);
  c->Func(intVar);
  c->Func(doubleVar);
  delete c;
}

This then outputs:

Base int 3
Base double 5.5
Child TT 3
Base double 5.5
Child TT 3
Base double 5.5

as I hoped, but I'm not sure why it works.

like image 292
user334066 Avatar asked May 06 '10 03:05

user334066


2 Answers

A class template may have virtual member functions.

A member function template cannot be virtual. That is, the following is invalid:

class C
{
public:
    template <typename T>
    virtual void f();
};

In addition, if a derived class has a member function template with the same name as a virtual function in a base class, it does not override the virtual function. So, if TemplateClass::Func had been a member function template, e.g.,

template <typename T>
void Func(T var) { /* ... */ }

it would not have overridden BaseClass::Func.

like image 123
James McNellis Avatar answered Oct 30 '22 06:10

James McNellis


It doesn't break the rule. The actual rule is 14.5.2/4:

A member function template shall not be virtual. [Example:

template <class T> struct AA {
  template <class C> virtual void g(C); // error
  virtual void f(); // OK
};
like image 40
Kirill V. Lyadvinsky Avatar answered Oct 30 '22 06:10

Kirill V. Lyadvinsky