0

I have a template function which is explicitly instantiated for Base class, but not for Derived class. How can I force the uses that pass a Derived class (or other derived classes) to match against the Base class?

Header file:

class Base {
};
class Derived : public Base {
};
class Derived2 : public Base {
};

template <typename Example> void function(Example &arg);

Implementation file:

// Explicitly instantiate Base class:
template void function<Base>(Base &arg);

// Define the template function:
template <typename Example> void function(Example &arg) {
  // Do something.
}

Because I have not explicitly instantiated function for Derived or Derived2, I get undefined references, however, I would like to bind against the Base class which is explicitly defined.

How can I force the template to resolve to the Base class for all objects derived from Base using C++-03?

Can I do it somehow with a specialization of the Derived class to the Base class definition?

WilliamKF
  • 41,123
  • 68
  • 193
  • 295
  • 6
    Instead of using a template, why not using a set of overloaded functions? That way the compiler knows which set is available and can choose accordingly. If you want to share implementation, have those functions forward to a template. – Sjoerd Jan 30 '13 at 19:53
  • If the argument to `function` should always be `Base&`, then `function` should not use a template parameter in its parameter list, and probably should not be a template at all. – aschepler Jan 30 '13 at 19:56
  • @Sjoerd because there are around 20 overloadings, I'd rather not have those in the header file and instead move them to the implementation as explicit instantiations and further, I now only have the definition showing up once instead of twenty times for each overloading. – WilliamKF Jan 30 '13 at 19:57
  • 1
    You can always cast the `arg` to a `(Base&)derived` when you call the function... :) – Alex Jan 30 '13 at 19:57
  • @Alex I'd prefer to not do this at the caller as that seems messy to me. I'd like to tell compiler in the header file to do this. – WilliamKF Jan 30 '13 at 19:58

1 Answers1

4

How about:

template <> void function(Derived &arg)
{
     function<Base>( arg );
}

EDIT: You can also do this with function overloading, as aschepler has suggested:

void function(Derived &arg)
{
     function<Base>( arg );
}

It's conceptually the same, although, I agree, slightly better :)

Alex
  • 7,728
  • 3
  • 35
  • 62
  • 1
    Prefer function overloading to explicit specialization of a function template: `inline void function(Derived& arg) { function(arg); }` – aschepler Jan 30 '13 at 20:10
  • @aschepler I think the compiler would match the template definition before matching the overloading you give here. – WilliamKF Jan 30 '13 at 20:43
  • 1
    When a non-template function and a function template specialization have the same function type, overload resolution always picks the non-template. – aschepler Jan 30 '13 at 20:50