19

If I define a class using a template such as

template<class K, class V>
class myclass {
...
};

is there a way to pass objects defined by myclass to functions without using a template for the function? In order words, for every function that accepts myclass objects, does it also need to be defined using template< class K, class V> ?

The main reason for this is that I would like define a set of static functions that act on myclass objects so that I may limit the scope of these functions within their cpp files and not in header files.

entitledX
  • 670
  • 1
  • 7
  • 13

7 Answers7

11

Make your template class inherit from some base class:

template<class K, class V>
class myclass : mybaseclass { ... };

where the base class declares the public functionality of the template as pure virtual. This way you only have one function rather than one function for each K, V combination.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
7

No, you cannot. A class template is not a class -- it is only a template. Only once you plug in the template parameters do you get a type, and for each different set of parameters you get a different, unrelated type.

Perhaps it's feasible for you to run some sort of type-erasing scheme, whereby you have a single container class which contains an abstract member pointer, and for each type you instantiate a concrete derived object. (Check out Boost.any.)

A bit like this:

class MyClassHolder { };

template <typename K, typename V>
class MyClassConcrete {  };

class MyClass
{
  MyClassHolder * p;

public:
  template <typename K, typename V> init(...)  // could be a constructor
  {
    p = new MyClassConcrete<K, V>();
  }
};

Now you can make your function accept a MyClass, but you have to add enough virtual functions to MyClassHolder, implement them in MyClassConcrete and expose them in MyClass that you can realise all your desired semantics.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
3

Yes, if you want your functions to be able to accept any instantiation of your template class they too must be template (typically with the same template parameters that are used for the class).

On the other hand, you can have your template class inherit from a non-template class that still allows you to operate the derived class via virtual functions. Also, to hide the type of your class and avoid riddling all your code of templates, there are the several techniques of type erasure.

Community
  • 1
  • 1
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
2

No, you will have to make the functions templated as well (unless of course they will be limited to only working with a specific specialization of myclass).

Jon
  • 428,835
  • 81
  • 738
  • 806
  • In that case, is there any way of declaring a function so that its scope is limited only to functions defined within the same header file? Looking for an equivalent of "static" for header files – entitledX Sep 17 '11 at 23:13
  • @entitledX: Not sure what you mean about the equivalent of `static`, but free functions are always publicly accessible so no, declaring a function would allow any code that sees the declaration to call it. – Jon Sep 17 '11 at 23:17
  • Anonymous namespaces can be used to achieve the same effect as static, not that it matters since it won't work as you want in a header file. Header file get, you know, **included** in the respective source files... – Staffan Sep 18 '11 at 08:02
2

You could do this:

void myfunc(const myclass<int, int>& mc) {}

Only if you wanted to be able to pass any type to your myclass argument in your function, would you need to make that myfunc a template too.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
1

Due to C++'s static nature, you must instantiate a copy of the function for each (K, V) pair in the source since the compiler will have to generate code to access each pair's members differently.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

While your reason is not entirely clear to me, yes, each function that takes a myclass as a parameter will also have to be templated on K and V. If you manage to abstract the basics, you could have each myclass< K, V > (which is a different type for each combination of K and V) inherit from a single base class that implements the functionality, or forwards it through virtual functions.

K-ballo
  • 80,396
  • 20
  • 159
  • 169